Skip to content

Commit f82ecfe

Browse files
authored
Merge pull request #511 from FStarLang/protz_renormalize_data_types
Renormalize data types properly
2 parents 3823e3d + ebff0d8 commit f82ecfe

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

lib/Checker.ml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,16 +1089,18 @@ and assert_cons_of env t id: fields_t =
10891089
checker_error env "the annotated type %a is not a variant type" ptyp (TAnonymous t)
10901090

10911091
and subtype env t1 t2 =
1092-
if Options.debug "checker" then
1093-
KPrint.bprintf "%a <=? %a\n" ptyp t1 ptyp t2;
10941092
let normalize t =
1095-
match MonomorphizationState.resolve (expand_abbrev env t) with
1093+
match MonomorphizationState.resolve_deep (expand_abbrev env t) with
10961094
| TBuf (TApp ((["Eurydice"], "derefed_slice"), [ t ]), _) ->
10971095
TApp ((["Eurydice"], "slice"), [t])
10981096
| t ->
10991097
t
11001098
in
1101-
match normalize t1, normalize t2 with
1099+
let t1 = normalize t1 in
1100+
let t2 = normalize t2 in
1101+
if Options.debug "checker" then
1102+
KPrint.bprintf "%a <=? %a\n" ptyp t1 ptyp t2;
1103+
match t1, t2 with
11021104
| TInt w1, TInt w2 when w1 = w2 ->
11031105
true
11041106
| TInt K.SizeT, TInt K.UInt32 when Options.wasm () ->
@@ -1184,6 +1186,8 @@ and subtype env t1 t2 =
11841186
subtype env t2 t1
11851187

11861188
| _ ->
1189+
if Options.debug "checker" then
1190+
MonomorphizationState.debug ();
11871191
false
11881192

11891193
and eqtype env t1 t2 =

lib/Monomorphization.ml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,17 @@ let monomorphize_data_types map = object(self)
298298
TQualified chosen_lid
299299
end)#visit_typ () t
300300

301+
(* We need to renormalize entries in the map for the Checker module. For
302+
instance, the map might contain `t (u v) -> t0` and `u v -> u0`, but at
303+
this stage, we will have a type error when trying to compare `t (u v)` and
304+
`t u0`, since the latter does not appear in the map. *)
305+
method private renormalize_entry (n, ts, cgs) chosen_lid =
306+
(* We do this on the fly to make sure that types that appear in ts have
307+
themselves been renormalized. *)
308+
let ts' = List.map resolve_deep ts in
309+
if not (Hashtbl.mem state (n, ts', cgs)) then
310+
Hashtbl.add state (n, ts', cgs) (Black, chosen_lid)
311+
301312
(* Compute the name of a given node in the graph. *)
302313
method private lid_of (n: node) =
303314
let lid, ts, cgs = n in
@@ -340,6 +351,7 @@ let monomorphize_data_types map = object(self)
340351
(* For tuples, we immediately know how to generate a definition. *)
341352
let fields = List.mapi (fun i arg -> Some (self#field_at i), (arg, false)) args in
342353
self#record (DType (chosen_lid, [ Common.Private ] @ flag, 0, 0, Flat fields));
354+
self#renormalize_entry n chosen_lid;
343355
Hashtbl.replace state n (Black, chosen_lid)
344356
end else begin
345357
(* This specific node has not been visited yet. *)
@@ -352,6 +364,7 @@ let monomorphize_data_types map = object(self)
352364
begin match Hashtbl.find map lid with
353365
| exception Not_found ->
354366
(* Unknown, external non-polymorphic lid, e.g. Prims.int *)
367+
self#renormalize_entry n chosen_lid;
355368
Hashtbl.replace state n (Black, chosen_lid)
356369
| flags, ((Variant _ | Flat _ | Union _) as def) when under_ref && not (Hashtbl.mem seen_declarations lid) ->
357370
(* Because this looks up a definition in the global map, the
@@ -382,10 +395,12 @@ let monomorphize_data_types map = object(self)
382395
let branches = List.map (fun (cons, fields) -> cons, subst fields) branches in
383396
let branches = self#visit_branches_t under_ref branches in
384397
self#record (DType (chosen_lid, flag @ flags, 0, 0, Variant branches));
398+
self#renormalize_entry n chosen_lid;
385399
Hashtbl.replace state n (Black, chosen_lid)
386400
| flags, Flat fields ->
387401
let fields = self#visit_fields_t_opt under_ref (subst fields) in
388402
self#record (DType (chosen_lid, flag @ flags, 0, 0, Flat fields));
403+
self#renormalize_entry n chosen_lid;
389404
Hashtbl.replace state n (Black, chosen_lid)
390405
| flags, Union fields ->
391406
let fields = List.map (fun (f, t) ->
@@ -394,13 +409,16 @@ let monomorphize_data_types map = object(self)
394409
f, t
395410
) fields in
396411
self#record (DType (chosen_lid, flag @ flags, 0, 0, Union fields));
412+
self#renormalize_entry n chosen_lid;
397413
Hashtbl.replace state n (Black, chosen_lid)
398414
| flags, Abbrev t ->
399415
let t = DeBruijn.subst_tn args t in
400416
let t = self#visit_typ under_ref t in
401417
self#record (DType (chosen_lid, flag @ flags, 0, 0, Abbrev t));
418+
self#renormalize_entry n chosen_lid;
402419
Hashtbl.replace state n (Black, chosen_lid)
403420
| _ ->
421+
self#renormalize_entry n chosen_lid;
404422
Hashtbl.replace state n (Black, chosen_lid)
405423
end
406424
end;

lib/MonomorphizationState.ml

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
11
open Ast
2+
open PrintAst.Ops
3+
4+
(* Various bits of state for monomorphization, the two most important being
5+
`state` (type monomorphization) and `generated_lids` (function
6+
monomorphization). *)
7+
8+
(* Monomorphization of data types. *)
29
type node = lident * typ list * cg list
310
type color = Gray | Black
11+
12+
(* Each polymorphic type `lid` applied to types `ts` and const generics `ts`
13+
appears in `state`, and maps to `monomorphized_lid`, the name of its
14+
monomorphized instance. *)
415
let state: (node, color * lident) Hashtbl.t = Hashtbl.create 41
516

17+
(* Because of polymorphic externals, one still encounters,
18+
post-monomorphizations, application nodes in types (e.g. after instantiating
19+
a polymorphic type scheme). The `resolve*` functions, below, normalize a type
20+
to only contain monomorphic type names (and no more type applications) *)
621
let resolve t: typ =
722
match t with
823
| TApp _ | TCgApp _ when Hashtbl.mem state (flatten_tapp t) ->
@@ -27,4 +42,17 @@ let resolve_deep = (object(self)
2742
resolve (TTuple ts)
2843
end)#visit_typ ()
2944

30-
let generated_lids: (lident * expr list * typ list, lident) Hashtbl.t = Hashtbl.create 41
45+
(* Monomorphization of functions *)
46+
type reverse_mapping = (lident * expr list * typ list, lident) Hashtbl.t
47+
48+
let generated_lids: reverse_mapping = Hashtbl.create 41
49+
50+
let debug () =
51+
Hashtbl.iter (fun (lid, ts, cgs) (_, monomorphized_lid) ->
52+
KPrint.bprintf "%a <%a> <%a> ~~> %a\n" plid lid pcgs cgs ptyps ts plid
53+
monomorphized_lid
54+
) state;
55+
Hashtbl.iter (fun (lid, es, ts) monomorphized_lid ->
56+
KPrint.bprintf "%a <%a> <%a> ~~> %a\n" plid lid pexprs es ptyps ts plid
57+
monomorphized_lid
58+
) generated_lids

0 commit comments

Comments
 (0)