diff options
author | Thomas Refis <thomas.refis@gmail.com> | 2019-08-13 15:11:16 +0100 |
---|---|---|
committer | Thomas Refis <thomas.refis@gmail.com> | 2019-09-11 14:21:05 -0400 |
commit | 50695d51c351a3c15530802eb5030d341602ff01 (patch) | |
tree | 10125338adbed60131a0e9854c5b92d85985da81 | |
parent | 83690293dcf942e14140a4841b1ff27a9b39ede0 (diff) | |
download | ocaml-pr8934.tar.gz |
PR#8934: used as a base for other PRspr8934
-rw-r--r-- | Changes | 3 | ||||
-rw-r--r-- | lambda/translcore.ml | 3 | ||||
-rw-r--r-- | ocamldoc/odoc_sig.ml | 2 | ||||
-rw-r--r-- | testsuite/tests/typing-sigsubst/test_locations.compilers.reference | 9 | ||||
-rw-r--r-- | toplevel/topdirs.ml | 6 | ||||
-rw-r--r-- | typing/ctype.ml | 5 | ||||
-rw-r--r-- | typing/datarepr.ml | 21 | ||||
-rw-r--r-- | typing/datarepr.mli | 5 | ||||
-rw-r--r-- | typing/env.ml | 222 | ||||
-rw-r--r-- | typing/env.mli | 14 | ||||
-rw-r--r-- | typing/includecore.ml | 13 | ||||
-rw-r--r-- | typing/includemod.ml | 6 | ||||
-rw-r--r-- | typing/mtype.ml | 2 | ||||
-rw-r--r-- | typing/predef.ml | 148 | ||||
-rw-r--r-- | typing/printtyp.ml | 1 | ||||
-rw-r--r-- | typing/subst.ml | 12 | ||||
-rw-r--r-- | typing/typeclass.ml | 25 | ||||
-rw-r--r-- | typing/typecore.ml | 186 | ||||
-rw-r--r-- | typing/typedecl.ml | 62 | ||||
-rw-r--r-- | typing/typedtree.mli | 35 | ||||
-rw-r--r-- | typing/typemod.ml | 89 | ||||
-rw-r--r-- | typing/types.ml | 60 | ||||
-rw-r--r-- | typing/types.mli | 44 |
23 files changed, 591 insertions, 382 deletions
@@ -74,6 +74,9 @@ Working version "*"). (Thomas Refis, review by ...) +- #8934: Stop relying on location to track usage + (Thomas Refis, review by ...) + ### Code generation and optimizations: - #8672: Optimise Switch code generation on booleans. diff --git a/lambda/translcore.ml b/lambda/translcore.ml index fc88d05559..5bd2f0680f 100644 --- a/lambda/translcore.ml +++ b/lambda/translcore.ml @@ -126,7 +126,8 @@ let rec push_defaults loc bindings cases partial = let param = Typecore.name_cases "param" cases in let desc = {val_type = pat.pat_type; val_kind = Val_reg; - val_attributes = []; Types.val_loc = Location.none; } + val_attributes = []; Types.val_loc = Location.none; + val_uid = Types.Uid.internal_not_actually_unique; } in let env = Env.add_value param desc exp.exp_env in let name = Ident.name param in diff --git a/ocamldoc/odoc_sig.ml b/ocamldoc/odoc_sig.ml index b695338e2a..e7cb90ab21 100644 --- a/ocamldoc/odoc_sig.ml +++ b/ocamldoc/odoc_sig.ml @@ -413,7 +413,7 @@ module Analyser = { Typedtree.ld_id; ld_mutable; ld_type; ld_loc; ld_attributes } = get_field env comments @@ {Types.ld_id; ld_mutable; ld_type=ld_type.Typedtree.ctyp_type; - ld_loc; ld_attributes } in + ld_loc; ld_attributes; ld_uid=Types.Uid.internal_not_actually_unique} in let open Typedtree in function | Cstr_tuple l -> diff --git a/testsuite/tests/typing-sigsubst/test_locations.compilers.reference b/testsuite/tests/typing-sigsubst/test_locations.compilers.reference index 86afba6715..c315538122 100644 --- a/testsuite/tests/typing-sigsubst/test_locations.compilers.reference +++ b/testsuite/tests/typing-sigsubst/test_locations.compilers.reference @@ -2,14 +2,7 @@ File "test_loc_type_eq.ml", line 1, characters 49-76: 1 | module M : Test_functor.S with type elt = unit = Test_functor.Apply (String) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Error: Signature mismatch: - Modules do not match: - sig - type elt = String.t - type t = Test_functor.Apply(String).t - val create : elt -> t - end - is not included in - sig type elt = unit type t val create : elt -> t end + ... Type declarations do not match: type elt = String.t is not included in diff --git a/toplevel/topdirs.ml b/toplevel/topdirs.ml index f4526692b6..6b1abe29f0 100644 --- a/toplevel/topdirs.ml +++ b/toplevel/topdirs.ml @@ -565,8 +565,10 @@ let () = ext_args = Cstr_tuple desc.cstr_args; ext_ret_type = ret_type; ext_private = Asttypes.Public; - Types.ext_loc = desc.cstr_loc; - Types.ext_attributes = desc.cstr_attributes; } + ext_loc = desc.cstr_loc; + ext_attributes = desc.cstr_attributes; + ext_uid = desc.cstr_uid; + } in [Sig_typext (id, ext, Text_exception, Exported)] ) diff --git a/typing/ctype.ml b/typing/ctype.ml index e4d385db3f..4dfa7501df 100644 --- a/typing/ctype.ml +++ b/typing/ctype.ml @@ -1232,6 +1232,7 @@ let new_declaration expansion_scope manifest = type_attributes = []; type_immediate = false; type_unboxed = unboxed_false_default_false; + type_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); } let existential_name cstr ty = match repr ty with @@ -4640,6 +4641,7 @@ let nondep_type_decl env mid is_covariant decl = type_attributes = decl.type_attributes; type_immediate = decl.type_immediate; type_unboxed = decl.type_unboxed; + type_uid = decl.type_uid; } with Nondep_cannot_erase _ as exn -> clear_hash (); @@ -4676,6 +4678,7 @@ let nondep_extension_constructor env ids ext = ext_private = ext.ext_private; ext_attributes = ext.ext_attributes; ext_loc = ext.ext_loc; + ext_uid = ext.ext_uid; } with Nondep_cannot_erase _ as exn -> clear_hash (); @@ -4719,6 +4722,7 @@ let nondep_class_declaration env ids decl = end; cty_loc = decl.cty_loc; cty_attributes = decl.cty_attributes; + cty_uid = decl.cty_uid; } in clear_hash (); @@ -4733,6 +4737,7 @@ let nondep_cltype_declaration env ids decl = clty_path = decl.clty_path; clty_loc = decl.clty_loc; clty_attributes = decl.clty_attributes; + clty_uid = decl.clty_uid; } in clear_hash (); diff --git a/typing/datarepr.ml b/typing/datarepr.ml index 9c997a78cd..374e538510 100644 --- a/typing/datarepr.ml +++ b/typing/datarepr.ml @@ -65,7 +65,7 @@ let constructor_existentials cd_args cd_res = in (tyl, existentials) -let constructor_args priv cd_args cd_res path rep = +let constructor_args ~current_unit priv cd_args cd_res path rep = let tyl, existentials = constructor_existentials cd_args cd_res in match cd_args with | Cstr_tuple l -> existentials, l, None @@ -91,13 +91,14 @@ let constructor_args priv cd_args cd_res path rep = type_attributes = []; type_immediate = false; type_unboxed; + type_uid = Uid.mk ~current_unit; } in existentials, [ newgenconstr path type_params ], Some tdecl -let constructor_descrs ty_path decl cstrs = +let constructor_descrs ~current_unit ty_path decl cstrs = let ty_res = newgenconstr ty_path decl.type_params in let num_consts = ref 0 and num_nonconsts = ref 0 and num_normal = ref 0 in List.iter @@ -107,7 +108,7 @@ let constructor_descrs ty_path decl cstrs = cstrs; let rec describe_constructors idx_const idx_nonconst = function [] -> [] - | {cd_id; cd_args; cd_res; cd_loc; cd_attributes} :: rem -> + | {cd_id; cd_args; cd_res; cd_loc; cd_attributes; cd_uid} :: rem -> let ty_res = match cd_res with | Some ty_res' -> ty_res' @@ -129,7 +130,7 @@ let constructor_descrs ty_path decl cstrs = then Record_unboxed true else Record_inlined idx_nonconst in - constructor_args decl.type_private cd_args cd_res + constructor_args ~current_unit decl.type_private cd_args cd_res (Path.Pdot (ty_path, cstr_name)) representation in let cstr = @@ -147,18 +148,19 @@ let constructor_descrs ty_path decl cstrs = cstr_loc = cd_loc; cstr_attributes = cd_attributes; cstr_inlined; + cstr_uid = cd_uid; } in (cd_id, cstr) :: descr_rem in describe_constructors 0 0 cstrs -let extension_descr path_ext ext = +let extension_descr ~current_unit path_ext ext = let ty_res = match ext.ext_ret_type with Some type_ret -> type_ret | None -> newgenconstr ext.ext_type_path ext.ext_type_params in let existentials, cstr_args, cstr_inlined = - constructor_args ext.ext_private ext.ext_args ext.ext_ret_type + constructor_args ~current_unit ext.ext_private ext.ext_args ext.ext_ret_type path_ext (Record_extension path_ext) in { cstr_name = Path.last path_ext; @@ -175,6 +177,7 @@ let extension_descr path_ext ext = cstr_loc = ext.ext_loc; cstr_attributes = ext.ext_attributes; cstr_inlined; + cstr_uid = ext.ext_uid; } let none = {desc = Ttuple []; level = -1; scope = Btype.generic_level; id = -1} @@ -185,6 +188,7 @@ let dummy_label = lbl_private = Public; lbl_loc = Location.none; lbl_attributes = []; + lbl_uid = Uid.internal_not_actually_unique; } let label_descrs ty_res lbls repres priv = @@ -203,6 +207,7 @@ let label_descrs ty_res lbls repres priv = lbl_private = priv; lbl_loc = l.ld_loc; lbl_attributes = l.ld_attributes; + lbl_uid = l.ld_uid; } in all_labels.(num) <- lbl; (l.ld_id, lbl) :: describe_labels (num+1) rest in @@ -225,9 +230,9 @@ let rec find_constr tag num_const num_nonconst = function let find_constr_by_tag tag cstrlist = find_constr tag 0 0 cstrlist -let constructors_of_type ty_path decl = +let constructors_of_type ~current_unit ty_path decl = match decl.type_kind with - | Type_variant cstrs -> constructor_descrs ty_path decl cstrs + | Type_variant cstrs -> constructor_descrs ~current_unit ty_path decl cstrs | Type_record _ | Type_abstract | Type_open -> [] let labels_of_type ty_path decl = diff --git a/typing/datarepr.mli b/typing/datarepr.mli index 30dc1f1f6c..e3962e3a07 100644 --- a/typing/datarepr.mli +++ b/typing/datarepr.mli @@ -19,13 +19,14 @@ open Types val extension_descr: - Path.t -> extension_constructor -> constructor_description + current_unit:string -> Path.t -> extension_constructor -> + constructor_description val labels_of_type: Path.t -> type_declaration -> (Ident.t * label_description) list val constructors_of_type: - Path.t -> type_declaration -> + current_unit:string -> Path.t -> type_declaration -> (Ident.t * constructor_description) list diff --git a/typing/env.ml b/typing/env.ml index 203d3c8911..03b45eaaff 100644 --- a/typing/env.ml +++ b/typing/env.ml @@ -27,16 +27,17 @@ module String = Misc.Stdlib.String let add_delayed_check_forward = ref (fun _ -> assert false) -let value_declarations : ((string * Location.t), (unit -> unit)) Hashtbl.t = - Hashtbl.create 16 - (* This table is used to usage of value declarations. A declaration is - identified with its name and location. The callback attached to a - declaration is called whenever the value is used explicitly - (lookup_value) or implicitly (inclusion test between signatures, - cf Includemod.value_descriptions). *) - -let type_declarations = Hashtbl.create 16 -let module_declarations = Hashtbl.create 16 +type 'a usage_tbl = (Types.Uid.t, 'a -> unit) Hashtbl.t +(** This table is used to usage of value declarations. + A declaration is identified by its uid. + The callback attached to a declaration is called whenever the value (or + type, or ...) is used explicitly (lookup_value, ...) or implicitly + (inclusion test between signatures, cf Includemod.value_descriptions, ...). +*) + +let value_declarations : unit usage_tbl = Hashtbl.create 16 +let type_declarations : unit usage_tbl = Hashtbl.create 16 +let module_declarations : unit usage_tbl = Hashtbl.create 16 type constructor_usage = Positive | Pattern | Privatize type constructor_usages = @@ -58,9 +59,7 @@ let add_constructor_usage priv cu usage = let constructor_usages () = {cu_positive = false; cu_pattern = false; cu_privatize = false} -let used_constructors : - (string * Location.t * string, (constructor_usage -> unit)) Hashtbl.t - = Hashtbl.create 16 +let used_constructors : constructor_usage usage_tbl = Hashtbl.create 16 (** Map indexed by the name of module components. *) module NameMap = String.Map @@ -407,7 +406,7 @@ and module_declaration_lazy = and module_components = { alerts: alerts; - loc: Location.t; + uid: Uid.t; comps: (components_maker, (module_components_repr, module_components_failure) result) @@ -648,7 +647,8 @@ let strengthen = aliasable:bool -> t -> module_type -> Path.t -> module_type) let md md_type = - {md_type; md_attributes=[]; md_loc=Location.none} + {md_type; md_attributes=[]; md_loc=Location.none + ;md_uid = Uid.internal_not_actually_unique} (* Print addresses *) @@ -703,10 +703,10 @@ let add_persistent_structure id env = else env -let components_of_module ~alerts ~loc env fs ps path addr mty = +let components_of_module ~alerts ~uid env fs ps path addr mty = { alerts; - loc; + uid; comps = EnvLazy.create { cm_env = env; cm_freshening_subst = fs; @@ -728,8 +728,13 @@ let sign_of_cmi ~freshen { Persistent_env.Persistent_signature.cmi; _ } = Misc.Stdlib.String.Map.empty flags in - let loc = Location.none in - let md = md (Mty_signature sign) in + let md = + { md_type = Mty_signature sign; + md_loc = Location.none; + md_attributes = []; + md_uid = Uid.of_compilation_unit_id id; + } + in let mda_address = EnvLazy.create_forced (Aident id) in let mda_declaration = EnvLazy.create (Subst.identity, Subst.Make_local, md) @@ -738,7 +743,7 @@ let sign_of_cmi ~freshen { Persistent_env.Persistent_signature.cmi; _ } = let freshening_subst = if freshen then (Some Subst.identity) else None in - components_of_module ~alerts ~loc + components_of_module ~alerts ~uid:md.md_uid empty freshening_subst Subst.identity path mda_address (Mty_signature sign) in @@ -1495,7 +1500,10 @@ let rec components_of_module_maker Datarepr.set_row_name final_decl (Subst.type_path prefixing_sub (Path.Pident id)); let constructors = - List.map snd (Datarepr.constructors_of_type path final_decl) in + List.map snd + (Datarepr.constructors_of_type ~current_unit:(get_unit_name ()) + path final_decl) + in let labels = List.map snd (Datarepr.labels_of_type path final_decl) in let tda = @@ -1517,7 +1525,10 @@ let rec components_of_module_maker env := store_type_infos id fresh_decl !env | Sig_typext(id, ext, _, _) -> let ext' = Subst.extension_constructor sub ext in - let descr = Datarepr.extension_descr path ext' in + let descr = + Datarepr.extension_descr ~current_unit:(get_unit_name ()) path + ext' + in let addr = next_address () in let cda = { cda_description = descr; cda_address = Some addr } in c.comp_constrs <- add_to_tbl (Ident.name id) cda c.comp_constrs @@ -1542,7 +1553,7 @@ let rec components_of_module_maker Builtin_attributes.alerts_of_attrs md.md_attributes in let comps = - components_of_module ~alerts ~loc:md.md_loc !env freshening_sub + components_of_module ~alerts ~uid:md.md_uid !env freshening_sub prefixing_sub path addr md.md_type in let mda = @@ -1602,13 +1613,15 @@ let rec components_of_module_maker (* Insertion of bindings by identifier + path *) -and check_usage loc id warn tbl = - if not loc.Location.loc_ghost && Warnings.is_active (warn "") then begin +and check_usage loc id uid warn tbl = + if not loc.Location.loc_ghost && + Uid.for_actual_declaration uid && + Warnings.is_active (warn "") + then begin let name = Ident.name id in - let key = (name, loc) in - if Hashtbl.mem tbl key then () + if Hashtbl.mem tbl uid then () else let used = ref false in - Hashtbl.add tbl key (fun () -> used := true); + Hashtbl.add tbl uid (fun () -> used := true); if not (name = "" || name.[0] = '_' || name.[0] = '#') then !add_delayed_check_forward @@ -1627,7 +1640,9 @@ and check_value_name name loc = and store_value ?check id addr decl env = check_value_name (Ident.name id) decl.val_loc; - Option.iter (fun f -> check_usage decl.val_loc id f value_declarations) check; + Option.iter + (fun f -> check_usage decl.val_loc id decl.val_uid f value_declarations) + check; let vda = { vda_description = decl; vda_address = addr } in { env with values = IdTbl.add id (Val_bound vda) env.values; @@ -1636,10 +1651,14 @@ and store_value ?check id addr decl env = and store_type ~check id info env = let loc = info.type_loc in if check then - check_usage loc id (fun s -> Warnings.Unused_type_declaration s) + check_usage loc id info.type_uid + (fun s -> Warnings.Unused_type_declaration s) type_declarations; let path = Pident id in - let constructors = Datarepr.constructors_of_type path info in + let constructors = + Datarepr.constructors_of_type path info + ~current_unit:(get_unit_name ()) + in let labels = Datarepr.labels_of_type path info in let descrs = (List.map snd constructors, List.map snd labels) in let tda = { tda_declaration = info; tda_descriptions = descrs } in @@ -1652,7 +1671,7 @@ and store_type ~check id info env = begin fun (_, cstr) -> let name = cstr.cstr_name in let loc = cstr.cstr_loc in - let k = (ty_name, loc, name) in + let k = cstr.cstr_uid in if not (Hashtbl.mem used_constructors k) then let used = constructor_usages () in Hashtbl.add used_constructors k (add_constructor_usage priv used); @@ -1693,16 +1712,17 @@ and store_type_infos id info env = and store_extension ~check id addr ext env = let loc = ext.ext_loc in - let cstr = Datarepr.extension_descr (Pident id) ext in + let cstr = + Datarepr.extension_descr ~current_unit:(get_unit_name ()) (Pident id) ext + in let cda = { cda_description = cstr; cda_address = Some addr } in if check && not loc.Location.loc_ghost && Warnings.is_active (Warnings.Unused_extension ("", false, false, false)) then begin let priv = ext.ext_private in let is_exception = Path.same ext.ext_type_path Predef.path_exn in - let ty_name = Path.last ext.ext_type_path in let name = cstr.cstr_name in - let k = (ty_name, loc, name) in + let k = cstr.cstr_uid in if not (Hashtbl.mem used_constructors k) then begin let used = constructor_usages () in Hashtbl.add used_constructors k (add_constructor_usage priv used); @@ -1722,7 +1742,8 @@ and store_extension ~check id addr ext env = and store_module ~check ~freshening_sub id addr presence md env = let loc = md.md_loc in - Option.iter (fun f -> check_usage loc id f module_declarations) check; + Option.iter + (fun f -> check_usage loc id md.md_uid f module_declarations) check; let alerts = Builtin_attributes.alerts_of_attrs md.md_attributes in let module_decl_lazy = match freshening_sub with @@ -1730,7 +1751,7 @@ and store_module ~check ~freshening_sub id addr presence md env = | Some s -> EnvLazy.create (s, Subst.Rescope (Ident.scope id), md) in let comps = - components_of_module ~alerts ~loc:md.md_loc + components_of_module ~alerts ~uid:md.md_uid env freshening_sub Subst.identity (Pident id) addr md.md_type in let mda = @@ -1781,7 +1802,7 @@ let components_of_functor_appl ~loc f env p1 p2 = ("the signature of " ^ Path.name p) mty; let comps = components_of_module ~alerts:Misc.Stdlib.String.Map.empty - ~loc:Location.none + ~uid:Uid.internal_not_actually_unique (*???*) env None Subst.identity p addr mty in @@ -2091,41 +2112,35 @@ let (initial_safe_string, initial_unsafe_string) = (* Tracking usage *) -let mark_module_used name loc = - match Hashtbl.find module_declarations (name, loc) with +let mark_module_used uid = + match Hashtbl.find module_declarations uid with | mark -> mark () | exception Not_found -> () -let mark_modtype_used _name _mtd = () +let mark_modtype_used _uid = () -let mark_value_used name vd = - match Hashtbl.find value_declarations (name, vd.val_loc) with +let mark_value_used uid = + match Hashtbl.find value_declarations uid with | mark -> mark () | exception Not_found -> () -let mark_type_used name td = - match Hashtbl.find type_declarations (name, td.type_loc) with +let mark_type_used uid = + match Hashtbl.find type_declarations uid with | mark -> mark () | exception Not_found -> () let mark_type_path_used env path = match find_type path env with - | decl -> mark_type_used (Path.last path) decl + | decl -> mark_type_used decl.type_uid | exception Not_found -> () -let mark_constructor_used usage ty_name cd = - let name = Ident.name cd.cd_id in - let loc = cd.cd_loc in - let k = (ty_name, loc, name) in - match Hashtbl.find used_constructors k with +let mark_constructor_used usage cd = + match Hashtbl.find used_constructors cd.cd_uid with | mark -> mark usage | exception Not_found -> () -let mark_extension_used usage name ext = - let ty_name = Path.last ext.ext_type_path in - let loc = ext.ext_loc in - let k = (ty_name, loc, name) in - match Hashtbl.find used_constructors k with +let mark_extension_used usage ext = + match Hashtbl.find used_constructors ext.ext_uid with | mark -> mark usage | exception Not_found -> () @@ -2136,9 +2151,7 @@ let mark_constructor_description_used usage env cstr = | _ -> assert false in mark_type_path_used env ty_path; - let ty_name = Path.last ty_path in - let k = (ty_name, cstr.cstr_loc, cstr.cstr_name) in - match Hashtbl.find used_constructors k with + match Hashtbl.find used_constructors cstr.cstr_uid with | mark -> mark usage | exception Not_found -> () @@ -2150,37 +2163,26 @@ let mark_label_description_used () env lbl = in mark_type_path_used env ty_path -let mark_class_used name cty = - match Hashtbl.find type_declarations (name, cty.cty_loc) with +let mark_class_used uid = + match Hashtbl.find type_declarations uid with | mark -> mark () | exception Not_found -> () -let mark_cltype_used name clty = - match Hashtbl.find type_declarations (name, clty.clty_loc) with +let mark_cltype_used uid = + match Hashtbl.find type_declarations uid with | mark -> mark () | exception Not_found -> () -let set_value_used_callback name vd callback = - let key = (name, vd.val_loc) in - try - let old = Hashtbl.find value_declarations key in - Hashtbl.replace value_declarations key (fun () -> old (); callback ()) - (* this is to support cases like: - let x = let x = 1 in x in x - where the two declarations have the same location - (e.g. resulting from Camlp4 expansion of grammar entries) *) - with Not_found -> - Hashtbl.add value_declarations key callback - -let set_type_used_callback name td callback = - let loc = td.type_loc in - if loc.Location.loc_ghost then () - else let key = (name, loc) in - let old = - try Hashtbl.find type_declarations key - with Not_found -> ignore - in - Hashtbl.replace type_declarations key (fun () -> callback old) +let set_value_used_callback vd callback = + Hashtbl.add value_declarations vd.val_uid callback + +let set_type_used_callback td callback = + if Uid.for_actual_declaration td.type_uid then + let old = + try Hashtbl.find type_declarations td.type_uid + with Not_found -> ignore + in + Hashtbl.replace type_declarations td.type_uid (fun () -> callback old) (* Lookup by name *) @@ -2213,10 +2215,10 @@ let report_value_unbound ~errors ~loc env reason lid = in may_lookup_error errors loc env (Unbound_value(lid, hint)) -let use_module ~use ~loc name path mda = +let use_module ~use ~loc path mda = if use then begin let comps = mda.mda_components in - mark_module_used name comps.loc; + mark_module_used comps.uid; Misc.Stdlib.String.Map.iter (fun kind message -> let message = if message = "" then "" else "\n" ^ message in @@ -2226,40 +2228,40 @@ let use_module ~use ~loc name path mda = comps.alerts end -let use_value ~use ~loc name path vda = +let use_value ~use ~loc path vda = if use then begin let desc = vda.vda_description in - mark_value_used name desc; + mark_value_used desc.val_uid; Builtin_attributes.check_alerts loc desc.val_attributes (Path.name path) end -let use_type ~use ~loc name path tda = +let use_type ~use ~loc path tda = if use then begin let decl = tda.tda_declaration in - mark_type_used name decl; + mark_type_used decl.type_uid; Builtin_attributes.check_alerts loc decl.type_attributes (Path.name path) end -let use_modtype ~use ~loc name path desc = +let use_modtype ~use ~loc path desc = if use then begin - mark_modtype_used name desc; + mark_modtype_used desc.mtd_uid; Builtin_attributes.check_alerts loc desc.mtd_attributes (Path.name path) end -let use_class ~use ~loc name path clda = +let use_class ~use ~loc path clda = if use then begin let desc = clda.clda_declaration in - mark_class_used name desc; + mark_class_used desc.cty_uid; Builtin_attributes.check_alerts loc desc.cty_attributes (Path.name path) end -let use_cltype ~use ~loc name path desc = +let use_cltype ~use ~loc path desc = if use then begin - mark_cltype_used name desc; + mark_cltype_used desc.clty_uid; Builtin_attributes.check_alerts loc desc.clty_attributes (Path.name path) end @@ -2292,7 +2294,7 @@ let lookup_ident_module (type a) (load : a load) ~errors ~use ~loc s env = in match data with | Mod_local mda -> begin - use_module ~use ~loc s path mda; + use_module ~use ~loc path mda; match load with | Load -> path, (mda : a) | Don't_load -> path, (() : a) @@ -2307,7 +2309,7 @@ let lookup_ident_module (type a) (load : a load) ~errors ~use ~loc s env = | Load -> begin match find_pers_mod s with | mda -> - use_module ~use ~loc s path mda; + use_module ~use ~loc path mda; path, (mda : a) | exception Not_found -> may_lookup_error errors loc env (Unbound_module (Lident s)) @@ -2317,7 +2319,7 @@ let lookup_ident_module (type a) (load : a load) ~errors ~use ~loc s env = let lookup_ident_value ~errors ~use ~loc name env = match IdTbl.find_name wrap_value ~mark:use name env.values with | (path, Val_bound vda) -> - use_value ~use ~loc name path vda; + use_value ~use ~loc path vda; path, vda.vda_description | (_, Val_unbound reason) -> report_value_unbound ~errors ~loc env reason (Lident name) @@ -2327,7 +2329,7 @@ let lookup_ident_value ~errors ~use ~loc name env = let lookup_ident_type ~errors ~use ~loc s env = match IdTbl.find_name wrap_identity ~mark:use s env.types with | (path, data) as res -> - use_type ~use ~loc s path data; + use_type ~use ~loc path data; res | exception Not_found -> may_lookup_error errors loc env (Unbound_type (Lident s)) @@ -2335,7 +2337,7 @@ let lookup_ident_type ~errors ~use ~loc s env = let lookup_ident_modtype ~errors ~use ~loc s env = match IdTbl.find_name wrap_identity ~mark:use s env.modtypes with | (path, data) as res -> - use_modtype ~use ~loc s path data; + use_modtype ~use ~loc path data; res | exception Not_found -> may_lookup_error errors loc env (Unbound_modtype (Lident s)) @@ -2343,7 +2345,7 @@ let lookup_ident_modtype ~errors ~use ~loc s env = let lookup_ident_class ~errors ~use ~loc s env = match IdTbl.find_name wrap_identity ~mark:use s env.classes with | (path, clda) -> - use_class ~use ~loc s path clda; + use_class ~use ~loc path clda; path, clda.clda_declaration | exception Not_found -> may_lookup_error errors loc env (Unbound_class (Lident s)) @@ -2351,7 +2353,7 @@ let lookup_ident_class ~errors ~use ~loc s env = let lookup_ident_cltype ~errors ~use ~loc s env = match IdTbl.find_name wrap_identity ~mark:use s env.cltypes with | (path, data) as res -> - use_cltype ~use ~loc s path data; + use_cltype ~use ~loc path data; res | exception Not_found -> may_lookup_error errors loc env (Unbound_cltype (Lident s)) @@ -2460,7 +2462,7 @@ and lookup_dot_module ~errors ~use ~loc l s env = match NameMap.find s comps.comp_modules with | mda -> let path = Pdot(p, s) in - use_module ~use ~loc s path mda; + use_module ~use ~loc path mda; (path, mda) | exception Not_found -> may_lookup_error errors loc env (Unbound_module (Ldot(l, s))) @@ -2472,7 +2474,7 @@ let lookup_dot_value ~errors ~use ~loc l s env = match NameMap.find s comps.comp_values with | vda -> let path = Pdot(path, s) in - use_value ~use ~loc s path vda; + use_value ~use ~loc path vda; (path, vda.vda_description) | exception Not_found -> may_lookup_error errors loc env (Unbound_value (Ldot(l, s), No_hint)) @@ -2482,7 +2484,7 @@ let lookup_dot_type ~errors ~use ~loc l s env = match NameMap.find s comps.comp_types with | tda -> let path = Pdot(p, s) in - use_type ~use ~loc s path tda; + use_type ~use ~loc path tda; (path, tda) | exception Not_found -> may_lookup_error errors loc env (Unbound_type (Ldot(l, s))) @@ -2492,7 +2494,7 @@ let lookup_dot_modtype ~errors ~use ~loc l s env = match NameMap.find s comps.comp_modtypes with | desc -> let path = Pdot(p, s) in - use_modtype ~use ~loc s path desc; + use_modtype ~use ~loc path desc; (path, desc) | exception Not_found -> may_lookup_error errors loc env (Unbound_modtype (Ldot(l, s))) @@ -2502,7 +2504,7 @@ let lookup_dot_class ~errors ~use ~loc l s env = match NameMap.find s comps.comp_classes with | clda -> let path = Pdot(p, s) in - use_class ~use ~loc s path clda; + use_class ~use ~loc path clda; (path, clda.clda_declaration) | exception Not_found -> may_lookup_error errors loc env (Unbound_class (Ldot(l, s))) @@ -2512,7 +2514,7 @@ let lookup_dot_cltype ~errors ~use ~loc l s env = match NameMap.find s comps.comp_cltypes with | desc -> let path = Pdot(p, s) in - use_cltype ~use ~loc s path desc; + use_cltype ~use ~loc path desc; (path, desc) | exception Not_found -> may_lookup_error errors loc env (Unbound_cltype (Ldot(l, s))) @@ -2731,7 +2733,7 @@ let lookup_instance_variable ?(use=true) ~loc name env = let desc = vda.vda_description in match desc.val_kind with | Val_ivar(mut, cl_num) -> - use_value ~use ~loc name path vda; + use_value ~use ~loc path vda; path, mut, cl_num, desc.val_type | _ -> lookup_error loc env (Not_an_instance_variable name) diff --git a/typing/env.mli b/typing/env.mli index 214ed233ea..7355758f7f 100644 --- a/typing/env.mli +++ b/typing/env.mli @@ -127,15 +127,15 @@ val add_required_global: Ident.t -> unit val has_local_constraints: t -> bool (* Mark definitions as used *) -val mark_value_used: string -> value_description -> unit -val mark_module_used: string -> Location.t -> unit -val mark_type_used: string -> type_declaration -> unit +val mark_value_used: Uid.t -> unit +val mark_module_used: Uid.t -> unit +val mark_type_used: Uid.t -> unit type constructor_usage = Positive | Pattern | Privatize val mark_constructor_used: - constructor_usage -> string -> constructor_declaration -> unit + constructor_usage -> constructor_declaration -> unit val mark_extension_used: - constructor_usage -> string -> extension_constructor -> unit + constructor_usage -> extension_constructor -> unit (* Lookup by long identifiers *) @@ -403,9 +403,9 @@ val in_signature: bool -> t -> t val is_in_signature: t -> bool val set_value_used_callback: - string -> value_description -> (unit -> unit) -> unit + value_description -> (unit -> unit) -> unit val set_type_used_callback: - string -> type_declaration -> ((unit -> unit) -> unit) -> unit + type_declaration -> ((unit -> unit) -> unit) -> unit (* Forward declaration to break mutual recursion with Includemod. *) val check_functor_application: diff --git a/typing/includecore.ml b/typing/includecore.ml index e4615354c3..cd1a3200b5 100644 --- a/typing/includecore.ml +++ b/typing/includecore.ml @@ -413,18 +413,15 @@ let type_declarations ?(equality = false) ~loc env ~mark name (_, Type_abstract) -> None | (Type_variant cstrs1, Type_variant cstrs2) -> if mark then begin - let mark usage name cstrs = - List.iter - (fun cstr -> - Env.mark_constructor_used usage name cstr) - cstrs + let mark usage cstrs = + List.iter (Env.mark_constructor_used usage) cstrs in let usage = if decl2.type_private = Public then Env.Positive else Env.Privatize in - mark usage name cstrs1; - if equality then mark Env.Positive (Path.name path) cstrs2 + mark usage cstrs1; + if equality then mark Env.Positive cstrs2 end; Option.map (fun var_err -> Variant_mismatch var_err) @@ -478,7 +475,7 @@ let extension_constructors ~loc env ~mark id ext1 ext2 = if ext2.ext_private = Public then Env.Positive else Env.Privatize in - Env.mark_extension_used usage (Ident.name id) ext1 + Env.mark_extension_used usage ext1 end; let ty1 = Btype.newgenty (Tconstr(ext1.ext_type_path, ext1.ext_type_params, ref Mnil)) diff --git a/typing/includemod.ml b/typing/includemod.ml index d92b0fe090..9c4b94f628 100644 --- a/typing/includemod.ml +++ b/typing/includemod.ml @@ -75,7 +75,7 @@ let mark_positive = function let value_descriptions ~loc env ~mark cxt subst id vd1 vd2 = Cmt_format.record_value_dependency vd1 vd2; if mark_positive mark then - Env.mark_value_used (Ident.name id) vd1; + Env.mark_value_used vd1.val_uid; let vd2 = Subst.value_description subst vd2 in try Includecore.value_descriptions ~loc env (Ident.name id) vd1 vd2 @@ -87,7 +87,7 @@ let value_descriptions ~loc env ~mark cxt subst id vd1 vd2 = let type_declarations ~loc env ~mark ?old_env:_ cxt subst id decl1 decl2 = let mark = mark_positive mark in if mark then - Env.mark_type_used (Ident.name id) decl1; + Env.mark_type_used decl1.type_uid; let decl2 = Subst.type_declaration subst decl2 in match Includecore.type_declarations ~loc env ~mark @@ -501,7 +501,7 @@ and module_declarations ~loc env ~mark cxt subst id1 md1 md2 = (Ident.name id1); let p1 = Path.Pident id1 in if mark_positive mark then - Env.mark_module_used (Ident.name id1) md1.md_loc; + Env.mark_module_used md1.md_uid; modtypes ~loc env ~mark (Module id1::cxt) subst (Mtype.strengthen ~aliasable:true env md1.md_type p1) md2.md_type diff --git a/typing/mtype.ml b/typing/mtype.ml index 38894e13ce..e36fd4f9e6 100644 --- a/typing/mtype.ml +++ b/typing/mtype.ml @@ -213,7 +213,7 @@ and nondep_sig_item env va ids = function with Ctype.Nondep_cannot_erase _ as exn -> match va with Co -> Sig_modtype(id, {mtd_type=None; mtd_loc=Location.none; - mtd_attributes=[]}, vis) + mtd_attributes=[]; mtd_uid = d.mtd_uid}, vis) | _ -> raise exn end | Sig_class(id, d, rs, vis) -> diff --git a/typing/predef.ml b/typing/predef.ml index 5399656d54..9cbd889e06 100644 --- a/typing/predef.ml +++ b/typing/predef.ml @@ -116,23 +116,6 @@ let path_match_failure = Pident ident_match_failure and path_assert_failure = Pident ident_assert_failure and path_undefined_recursive_module = Pident ident_undefined_recursive_module -let decl_abstr = - {type_params = []; - type_arity = 0; - type_kind = Type_abstract; - type_loc = Location.none; - type_private = Asttypes.Public; - type_manifest = None; - type_variance = []; - type_is_newtype = false; - type_expansion_scope = lowest_level; - type_attributes = []; - type_immediate = false; - type_unboxed = unboxed_false_default_false; - } - -let decl_abstr_imm = {decl_abstr with type_immediate = true} - let cstr id args = { cd_id = id; @@ -140,6 +123,7 @@ let cstr id args = cd_res = None; cd_loc = Location.none; cd_attributes = []; + cd_uid = Uid.of_predef_id id; } let ident_false = ident_create "false" @@ -149,47 +133,49 @@ and ident_nil = ident_create "[]" and ident_cons = ident_create "::" and ident_none = ident_create "None" and ident_some = ident_create "Some" -let common_initial_env add_type add_extension empty_env = - let decl_bool = - {decl_abstr with - type_kind = Type_variant([cstr ident_false []; cstr ident_true []]); - type_immediate = true} - and decl_unit = - {decl_abstr with - type_kind = Type_variant([cstr ident_void []]); - type_immediate = true} - and decl_exn = - {decl_abstr with - type_kind = Type_open} - and decl_array = - let tvar = newgenvar() in - {decl_abstr with - type_params = [tvar]; - type_arity = 1; - type_variance = [Variance.full]} - and decl_list = - let tvar = newgenvar() in - {decl_abstr with - type_params = [tvar]; - type_arity = 1; - type_kind = - Type_variant([cstr ident_nil []; cstr ident_cons [tvar; type_list tvar]]); - type_variance = [Variance.covariant]} - and decl_option = - let tvar = newgenvar() in - {decl_abstr with - type_params = [tvar]; - type_arity = 1; - type_kind = Type_variant([cstr ident_none []; cstr ident_some [tvar]]); - type_variance = [Variance.covariant]} - and decl_lazy_t = - let tvar = newgenvar() in - {decl_abstr with - type_params = [tvar]; - type_arity = 1; - type_variance = [Variance.covariant]} + +let mk_add_type add_type type_ident + ?manifest ?(immediate=false) ?(kind=Type_abstract) env = + let decl = + {type_params = []; + type_arity = 0; + type_kind = kind; + type_loc = Location.none; + type_private = Asttypes.Public; + type_manifest = manifest; + type_variance = []; + type_is_newtype = false; + type_expansion_scope = lowest_level; + type_attributes = []; + type_immediate = immediate; + type_unboxed = unboxed_false_default_false; + type_uid = Uid.of_predef_id type_ident; + } in + add_type type_ident decl env +let common_initial_env add_type add_extension empty_env = + let add_type = mk_add_type add_type + and add_type1 type_ident ~variance ?(kind=fun _ -> Type_abstract) env = + let param = newgenvar () in + let decl = + {type_params = [param]; + type_arity = 1; + type_kind = kind param; + type_loc = Location.none; + type_private = Asttypes.Public; + type_manifest = None; + type_variance = [variance]; + type_is_newtype = false; + type_expansion_scope = lowest_level; + type_attributes = []; + type_immediate = false; + type_unboxed = unboxed_false_default_false; + type_uid = Uid.of_predef_id type_ident; + } + in + add_type type_ident decl env + in let add_extension id l = add_extension id { ext_type_path = path_exn; @@ -200,7 +186,9 @@ let common_initial_env add_type add_extension empty_env = ext_loc = Location.none; ext_attributes = [Ast_helper.Attr.mk (Location.mknoloc "ocaml.warn_on_literal_pattern") - (Parsetree.PStr [])] } + (Parsetree.PStr [])]; + ext_uid = Uid.of_predef_id id; + } in add_extension ident_match_failure [newgenty (Ttuple[type_string; type_int; type_int])] ( @@ -217,29 +205,37 @@ let common_initial_env add_type add_extension empty_env = [newgenty (Ttuple[type_string; type_int; type_int])] ( add_extension ident_undefined_recursive_module [newgenty (Ttuple[type_string; type_int; type_int])] ( - add_type ident_int64 decl_abstr ( - add_type ident_int32 decl_abstr ( - add_type ident_nativeint decl_abstr ( - add_type ident_lazy_t decl_lazy_t ( - add_type ident_option decl_option ( - add_type ident_list decl_list ( - add_type ident_array decl_array ( - add_type ident_exn decl_exn ( - add_type ident_unit decl_unit ( - add_type ident_bool decl_bool ( - add_type ident_float decl_abstr ( - add_type ident_string decl_abstr ( - add_type ident_char decl_abstr_imm ( - add_type ident_int decl_abstr_imm ( - add_type ident_extension_constructor decl_abstr ( - add_type ident_floatarray decl_abstr ( + add_type ident_int64 ( + add_type ident_int32 ( + add_type ident_nativeint ( + add_type1 ident_lazy_t ~variance:Variance.covariant ( + add_type1 ident_option ~variance:Variance.covariant + ~kind:(fun tvar -> + Type_variant([cstr ident_none []; cstr ident_some [tvar]]) + ) ( + add_type1 ident_list ~variance:Variance.covariant + ~kind:(fun tvar -> + Type_variant([cstr ident_nil []; cstr ident_cons [tvar; type_list tvar]]) + ) ( + add_type1 ident_array ~variance:Variance.full ( + add_type ident_exn ~kind:Type_open ( + add_type ident_unit ~immediate:true + ~kind:(Type_variant([cstr ident_void []])) ( + add_type ident_bool ~immediate:true + ~kind:(Type_variant([cstr ident_false []; cstr ident_true []])) ( + add_type ident_float ( + add_type ident_string ( + add_type ident_char ~immediate:true ( + add_type ident_int ~immediate:true ( + add_type ident_extension_constructor ( + add_type ident_floatarray ( empty_env)))))))))))))))))))))))))))) let build_initial_env add_type add_exception empty_env = let common = common_initial_env add_type add_exception empty_env in - let safe_string = add_type ident_bytes decl_abstr common in - let decl_bytes_unsafe = {decl_abstr with type_manifest = Some type_string} in - let unsafe_string = add_type ident_bytes decl_bytes_unsafe common in + let add_type = mk_add_type add_type in + let safe_string = add_type ident_bytes common in + let unsafe_string = add_type ident_bytes ~manifest:type_string common in (safe_string, unsafe_string) let builtin_values = diff --git a/typing/printtyp.ml b/typing/printtyp.ml index c39f04d3ce..941e78f62d 100644 --- a/typing/printtyp.ml +++ b/typing/printtyp.ml @@ -1572,6 +1572,7 @@ let dummy = type_attributes = []; type_immediate = false; type_unboxed = unboxed_false_default_false; + type_uid = Uid.internal_not_actually_unique; } let hide ids env = List.fold_right diff --git a/typing/subst.ml b/typing/subst.ml index 5ae3d1b4b6..576dd7cce3 100644 --- a/typing/subst.ml +++ b/typing/subst.ml @@ -263,6 +263,7 @@ let label_declaration copy_scope s l = ld_type = typexp copy_scope s l.ld_type; ld_loc = loc s l.ld_loc; ld_attributes = attrs s l.ld_attributes; + ld_uid = l.ld_uid; } let constructor_arguments copy_scope s = function @@ -278,6 +279,7 @@ let constructor_declaration copy_scope s c = cd_res = Option.map (typexp copy_scope s) c.cd_res; cd_loc = loc s c.cd_loc; cd_attributes = attrs s c.cd_attributes; + cd_uid = c.cd_uid; } let type_declaration' copy_scope s decl = @@ -306,6 +308,7 @@ let type_declaration' copy_scope s decl = type_attributes = attrs s decl.type_attributes; type_immediate = decl.type_immediate; type_unboxed = decl.type_unboxed; + type_uid = decl.type_uid; } let type_declaration s decl = @@ -346,6 +349,7 @@ let class_declaration' copy_scope s decl = end; cty_loc = loc s decl.cty_loc; cty_attributes = attrs s decl.cty_attributes; + cty_uid = decl.cty_uid; } let class_declaration s decl = @@ -358,6 +362,7 @@ let cltype_declaration' copy_scope s decl = clty_path = type_path s decl.clty_path; clty_loc = loc s decl.clty_loc; clty_attributes = attrs s decl.clty_attributes; + clty_uid = decl.clty_uid; } let cltype_declaration s decl = @@ -371,6 +376,7 @@ let value_description' copy_scope s descr = val_kind = descr.val_kind; val_loc = loc s descr.val_loc; val_attributes = attrs s descr.val_attributes; + val_uid = descr.val_uid; } let value_description s descr = @@ -383,7 +389,9 @@ let extension_constructor' copy_scope s ext = ext_ret_type = Option.map (typexp copy_scope s) ext.ext_ret_type; ext_private = ext.ext_private; ext_attributes = attrs s ext.ext_attributes; - ext_loc = if s.for_saving then Location.none else ext.ext_loc; } + ext_loc = if s.for_saving then Location.none else ext.ext_loc; + ext_uid = ext.ext_uid; + } let extension_constructor s ext = For_copy.with_scope @@ -505,6 +513,7 @@ and module_declaration scoping s decl = md_type = modtype scoping s decl.md_type; md_attributes = attrs s decl.md_attributes; md_loc = loc s decl.md_loc; + md_uid = decl.md_uid; } and modtype_declaration scoping s decl = @@ -512,6 +521,7 @@ and modtype_declaration scoping s decl = mtd_type = Option.map (modtype scoping s) decl.mtd_type; mtd_attributes = attrs s decl.mtd_attributes; mtd_loc = loc s decl.mtd_loc; + mtd_uid = decl.mtd_uid; } diff --git a/typing/typeclass.ml b/typing/typeclass.ml index 3e39991ce7..0c1038b390 100644 --- a/typing/typeclass.ml +++ b/typing/typeclass.ml @@ -263,7 +263,8 @@ let enter_met_env ?check loc lab kind unbound_kind ty val_env met_env par_env = let (id, met_env) = Env.enter_value ?check lab {val_type = ty; val_kind = kind; - val_attributes = []; Types.val_loc = loc} met_env + val_attributes = []; Types.val_loc = loc; + val_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); } met_env in (id, val_env, met_env, par_env) @@ -1194,6 +1195,7 @@ and class_expr_aux cl_num val_env met_env scl = cl_num); val_attributes = []; Types.val_loc = vd.Types.val_loc; + val_uid = vd.val_uid; } in let id' = Ident.create_local (Ident.name id) in @@ -1286,7 +1288,7 @@ let rec approx_description ct = (*******************************) -let temp_abbrev loc env id arity = +let temp_abbrev loc env id arity uid = let params = ref [] in for _i = 1 to arity do params := Ctype.newvar () :: !params @@ -1306,17 +1308,18 @@ let temp_abbrev loc env id arity = type_attributes = []; (* or keep attrs from the class decl? *) type_immediate = false; type_unboxed = unboxed_false_default_false; + type_uid = uid; } env in (!params, ty, env) let initial_env define_class approx - (res, env) (cl, id, ty_id, obj_id, cl_id) = + (res, env) (cl, id, ty_id, obj_id, cl_id, uid) = (* Temporary abbreviations *) let arity = List.length cl.pci_params in - let (obj_params, obj_ty, env) = temp_abbrev cl.pci_loc env obj_id arity in - let (cl_params, cl_ty, env) = temp_abbrev cl.pci_loc env cl_id arity in + let (obj_params, obj_ty, env) = temp_abbrev cl.pci_loc env obj_id arity uid in + let (cl_params, cl_ty, env) = temp_abbrev cl.pci_loc env cl_id arity uid in (* Temporary type for the class constructor *) let constr_type = approx cl.pci_expr in @@ -1340,6 +1343,7 @@ let initial_env define_class approx end; cty_loc = Location.none; cty_attributes = []; + cty_uid = uid; } in let env = @@ -1350,6 +1354,7 @@ let initial_env define_class approx clty_path = unbound_class; clty_loc = Location.none; clty_attributes = []; + clty_uid = uid; } ( if define_class then @@ -1480,6 +1485,7 @@ let class_infos define_class kind clty_path = Path.Pident obj_id; clty_loc = cl.pci_loc; clty_attributes = cl.pci_attributes; + clty_uid = dummy_class.cty_uid; } and clty = {cty_params = params; cty_type = typ; @@ -1492,6 +1498,7 @@ let class_infos define_class kind end; cty_loc = cl.pci_loc; cty_attributes = cl.pci_attributes; + cty_uid = dummy_class.cty_uid; } in dummy_class.cty_type <- typ; @@ -1529,6 +1536,7 @@ let class_infos define_class kind clty_path = Path.Pident obj_id; clty_loc = cl.pci_loc; clty_attributes = cl.pci_attributes; + clty_uid = dummy_class.cty_uid; } and clty = {cty_params = params'; cty_type = typ'; @@ -1541,6 +1549,7 @@ let class_infos define_class kind end; cty_loc = cl.pci_loc; cty_attributes = cl.pci_attributes; + cty_uid = dummy_class.cty_uid; } in let obj_abbr = @@ -1556,6 +1565,7 @@ let class_infos define_class kind type_attributes = []; (* or keep attrs from cl? *) type_immediate = false; type_unboxed = unboxed_false_default_false; + type_uid = dummy_class.cty_uid; } in let (cl_params, cl_ty) = @@ -1576,6 +1586,7 @@ let class_infos define_class kind type_attributes = []; (* or keep attrs from cl? *) type_immediate = false; type_unboxed = unboxed_false_default_false; + type_uid = dummy_class.cty_uid; } in ((cl, id, clty, ty_id, cltydef, obj_id, obj_abbr, cl_id, cl_abbr, ci_params, @@ -1732,7 +1743,9 @@ let type_classes define_class approx kind env cls = Ident.create_scoped ~scope cl.pci_name.txt, Ident.create_scoped ~scope cl.pci_name.txt, Ident.create_scoped ~scope cl.pci_name.txt, - Ident.create_scoped ~scope ("#" ^ cl.pci_name.txt))) + Ident.create_scoped ~scope ("#" ^ cl.pci_name.txt), + Uid.mk ~current_unit:(Env.get_unit_name ()) + )) cls in Ctype.begin_class_def (); diff --git a/typing/typecore.ml b/typing/typecore.ml index 6106db8b2f..b1780491de 100644 --- a/typing/typecore.ml +++ b/typing/typecore.ml @@ -1547,6 +1547,7 @@ let add_pattern_variables ?check ?check_as env pv = Env.add_value ?check pv_id {val_type = pv_type; val_kind = Val_reg; Types.val_loc = pv_loc; val_attributes = pv_attributes; + val_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); } env ) pv env @@ -1570,7 +1571,11 @@ let type_pattern_list no_existentials env spatl scope expected_tys allow = in let patl = List.map2 type_pat spatl expected_tys in let pvs = get_ref pattern_variables in - let unpacks = get_ref module_variables in + let unpacks = + List.map (fun (name, loc) -> + name, loc, Uid.mk ~current_unit:(Env.get_unit_name ()) + ) (get_ref module_variables) + in let new_env = add_pattern_variables !new_env pvs in (patl, new_env, get_ref pattern_force, pvs, unpacks) @@ -1584,23 +1589,38 @@ let type_class_arg_pattern cl_num val_env met_env l spat = end; List.iter (fun f -> f()) (get_ref pattern_force); if is_optional l then unify_pat val_env pat (type_option (newvar ())); - let (pv, met_env) = + let (pv, val_env, met_env) = List.fold_right - (fun {pv_id; pv_type; pv_loc; pv_as_var; pv_attributes} (pv, env) -> + (fun {pv_id; pv_type; pv_loc; pv_as_var; pv_attributes} + (pv, val_env, met_env) -> let check s = if pv_as_var then Warnings.Unused_var s else Warnings.Unused_var_strict s in - let id' = Ident.create_local (Ident.name pv_id) in - ((id', pv_id, pv_type)::pv, - Env.add_value id' {val_type = pv_type; - val_kind = Val_ivar (Immutable, cl_num); - val_attributes = pv_attributes; - Types.val_loc = pv_loc; - } ~check - env)) - !pattern_variables ([], met_env) + let id' = Ident.rename pv_id in + let val_uid = Uid.mk ~current_unit:(Env.get_unit_name ()) in + let val_env = + Env.add_value pv_id + { val_type = pv_type + ; val_kind = Val_reg + ; val_attributes = pv_attributes + ; val_loc = pv_loc + ; val_uid + } + val_env + in + let met_env = + Env.add_value id' ~check + { val_type = pv_type + ; val_kind = Val_ivar (Immutable, cl_num) + ; val_attributes = pv_attributes + ; val_loc = pv_loc + ; val_uid + } + met_env + in + ((id', pv_id, pv_type)::pv, val_env, met_env)) + !pattern_variables ([], val_env, met_env) in - let val_env = add_pattern_variables val_env (get_ref pattern_variables) in (pat, pv, val_env, met_env) let type_self_pattern cl_num privty val_env met_env par_env spat = @@ -1623,12 +1643,13 @@ let type_self_pattern cl_num privty val_env met_env par_env spat = (val_env, met_env, par_env) -> let name = Ident.name pv_id in (Env.enter_unbound_value name Val_unbound_self val_env, - Env.add_value pv_id {val_type = pv_type; - val_kind = - Val_self (meths, vars, cl_num, privty); - val_attributes = pv_attributes; - Types.val_loc = pv_loc; - } + Env.add_value pv_id + {val_type = pv_type; + val_kind = Val_self (meths, vars, cl_num, privty); + val_attributes = pv_attributes; + val_loc = pv_loc; + val_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); + } ~check:(fun s -> if pv_as_var then Warnings.Unused_var s else Warnings.Unused_var_strict s) met_env, @@ -2008,20 +2029,6 @@ let create_package_type loc env (p, l) = in (s, fields, ty) - let wrap_unpacks sexp unpacks = - let open Ast_helper in - List.fold_left - (fun sexp (name, loc) -> - Exp.letmodule ~loc:{ sexp.pexp_loc with loc_ghost = true } - ~attrs:[Attr.mk (mknoloc "#modulepat") (PStr [])] - { name with txt = Some name.txt } - (Mod.unpack ~loc - (Exp.ident ~loc:name.loc (mkloc (Longident.Lident name.txt) - name.loc))) - sexp - ) - sexp unpacks - (* Helpers for type_cases *) let contains_variant_either ty = @@ -2278,9 +2285,7 @@ and type_expect_ in let (pat_exp_list, new_env, unpacks) = type_let existential_context env rec_flag spat_sexp_list scp true in - let body = - type_expect new_env (wrap_unpacks sbody unpacks) - ty_expected_explained in + let body = type_unpacks new_env unpacks sbody ty_expected_explained in let () = if rec_flag = Recursive then check_recursive_bindings env pat_exp_list @@ -2675,9 +2680,13 @@ and type_expect_ match param.ppat_desc with | Ppat_any -> Ident.create_local "_for", env | Ppat_var {txt} -> - Env.enter_value txt {val_type = instance Predef.type_int; - val_attributes = []; - val_kind = Val_reg; Types.val_loc = loc; } env + Env.enter_value txt + {val_type = instance Predef.type_int; + val_attributes = []; + val_kind = Val_reg; + val_loc = loc; + val_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); + } env ~check:(fun s -> Warnings.Unused_for_index s) | _ -> raise (Error (param.ppat_loc, env, Invalid_for_loop_index)) @@ -2832,7 +2841,9 @@ and type_expect_ {val_type = method_type; val_kind = Val_reg; val_attributes = []; - Types.val_loc = Location.none} + val_loc = Location.none; + val_uid = Uid.internal_not_actually_unique; + } in let exp_env = Env.add_value method_id method_desc env in let exp = @@ -2997,7 +3008,8 @@ and type_expect_ in let scope = create_scope () in let md = - { md_type = modl.mod_type; md_attributes = []; md_loc = name.loc } + { md_type = modl.mod_type; md_attributes = []; md_loc = name.loc; + md_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); } in let (id, new_env) = match name.txt with @@ -3136,6 +3148,7 @@ and type_expect_ type_attributes = []; type_immediate = false; type_unboxed = unboxed_false_default_false; + type_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); } in let scope = create_scope () in @@ -3765,7 +3778,9 @@ and type_argument ?explanation ?recarg env sarg ty_expected' ty_expected = let desc = { val_type = ty; val_kind = Val_reg; val_attributes = []; - Types.val_loc = Location.none} + val_loc = Location.none; + val_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); + } in let exp_env = Env.add_value id desc env in {pat_desc = Tpat_var (id, mknoloc name); pat_type = ty;pat_extra=[]; @@ -4113,6 +4128,59 @@ and type_statement ?explanation env sexp = exp end +and type_unpacks ?in_function env unpacks sbody expected_ty = + let ty = newvar() in + (* remember original level *) + let extended_env, tunpacks = + List.fold_left (fun (env, unpacks) (name, loc, uid) -> + begin_def (); + let context = Typetexp.narrow () in + let modl = + !type_module env + Ast_helper.( + Mod.unpack ~loc + (Exp.ident ~loc:name.loc (mkloc (Longident.Lident name.txt) + name.loc))) + in + Mtype.lower_nongen ty.level modl.mod_type; + let pres = + match modl.mod_type with + | Mty_alias _ -> Mp_absent + | _ -> Mp_present + in + let scope = create_scope () in + let md = + { md_type = modl.mod_type; md_attributes = []; md_loc = name.loc; + md_uid = uid; } + in + let (id, env) = + Env.enter_module_declaration ~scope name.txt pres md env + in + Typetexp.widen context; + env, (id, name, pres, modl) :: unpacks + ) (env, []) unpacks + in + (* ideally, we should catch Expr_type_clash errors + in type_expect triggered by escaping identifiers from the local module + and refine them into Scoping_let_module errors + *) + let body = type_expect ?in_function extended_env sbody expected_ty in + let exp_loc = { body.exp_loc with loc_ghost = true } in + let exp_attributes = [Ast_helper.Attr.mk (mknoloc "#modulepat") (PStr [])] in + List.fold_left (fun body (id, name, pres, modl) -> + (* go back to parent level *) + end_def (); + Ctype.unify_var extended_env ty body.exp_type; + re { + exp_desc = Texp_letmodule(Some id, { name with txt = Some name.txt }, + pres, modl, body); + exp_loc; + exp_attributes; + exp_extra = []; + exp_type = ty; + exp_env = env } + ) body tunpacks + (* Typing of match cases *) and type_cases ?exception_allowed ?in_function env ty_arg ty_res partial_flag loc caselist = @@ -4238,7 +4306,11 @@ and type_cases ?exception_allowed ?in_function env ty_arg ty_res partial_flag ~check:(fun s -> Warnings.Unused_var_strict s) ~check_as:(fun s -> Warnings.Unused_var s) in - let sexp = wrap_unpacks pc_rhs unpacks in + let unpacks = + List.map (fun (name, loc) -> + name, loc, Uid.mk ~current_unit:(Env.get_unit_name ()) + ) unpacks + in let ty_res' = if !Clflags.principal then begin begin_def (); @@ -4260,11 +4332,12 @@ and type_cases ?exception_allowed ?in_function env ty_arg ty_res partial_flag | None -> None | Some scond -> Some - (type_expect ext_env (wrap_unpacks scond unpacks) + (type_unpacks ext_env unpacks scond (mk_expected ~explanation:When_guard Predef.type_bool)) in let exp = - type_expect ?in_function ext_env sexp (mk_expected ty_res') in + type_unpacks ?in_function ext_env unpacks pc_rhs (mk_expected ty_res') + in { c_lhs = pat; c_guard = guard; @@ -4467,15 +4540,13 @@ and type_let ((if !some_used then check_strict else check) name) ); Env.set_value_used_callback - name vd + vd (fun () -> match !current_slot with | Some slot -> - slot := (name, vd) :: !slot; rec_needed := true + slot := vd.val_uid :: !slot; rec_needed := true | None -> - List.iter - (fun (name, vd) -> Env.mark_value_used name vd) - (get_ref slot); + List.iter Env.mark_value_used (get_ref slot); used := true; some_used := true ) @@ -4489,8 +4560,6 @@ and type_let let exp_list = List.map2 (fun {pvb_expr=sexp; pvb_attributes; _} (pat, slot) -> - let sexp = - if rec_flag = Recursive then wrap_unpacks sexp unpacks else sexp in if is_recursive then current_slot := slot; match pat.pat_type.desc with | Tpoly (ty, tl) -> @@ -4502,15 +4571,22 @@ and type_let generalize_structure ty' end; let exp = - Builtin_attributes.warning_scope pvb_attributes - (fun () -> type_expect exp_env sexp (mk_expected ty')) + Builtin_attributes.warning_scope pvb_attributes (fun () -> + if rec_flag = Recursive then + type_unpacks exp_env unpacks sexp (mk_expected ty') + else + type_expect exp_env sexp (mk_expected ty') + ) in end_def (); check_univars env true "definition" exp pat.pat_type vars; {exp with exp_type = instance exp.exp_type} | _ -> Builtin_attributes.warning_scope pvb_attributes (fun () -> - type_expect exp_env sexp (mk_expected pat.pat_type))) + if rec_flag = Recursive then + type_unpacks exp_env unpacks sexp (mk_expected pat.pat_type) + else + type_expect exp_env sexp (mk_expected pat.pat_type))) spat_sexp_list pat_slot_list in current_slot := None; if is_recursive && not !rec_needed then begin diff --git a/typing/typedecl.ml b/typing/typedecl.ml index 4ad1fb6e84..50fa078b84 100644 --- a/typing/typedecl.ml +++ b/typing/typedecl.ml @@ -84,7 +84,7 @@ let add_type ~check id decl env = Builtin_attributes.warning_scope ~ppwarning:false decl.type_attributes (fun () -> Env.add_type ~check id decl env) -let enter_type rec_flag env sdecl id = +let enter_type rec_flag env sdecl (id, uid) = let needed = match rec_flag with | Asttypes.Nonrecursive -> @@ -115,6 +115,7 @@ let enter_type rec_flag env sdecl id = type_attributes = sdecl.ptype_attributes; type_immediate = false; type_unboxed = unboxed_false_default_false; + type_uid = uid; } in add_type ~check:true id decl env @@ -220,7 +221,8 @@ let transl_labels env closed lbls = ld_mutable = ld.ld_mutable; ld_type = ty; ld_loc = ld.ld_loc; - ld_attributes = ld.ld_attributes + ld_attributes = ld.ld_attributes; + ld_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); } ) lbls in @@ -339,7 +341,7 @@ let rec check_unboxed_gadt_arg loc univ env ty = in the same recursive definition. In this case we don't have to check because we will also check that other type for correctness. *) -let transl_declaration env sdecl id = +let transl_declaration env sdecl (id, uid) = (* Bind type parameters *) reset_type_variables(); Ctype.begin_def (); @@ -454,7 +456,8 @@ let transl_declaration env sdecl id = cd_args = args; cd_res = ret_type; cd_loc = scstr.pcd_loc; - cd_attributes = scstr.pcd_attributes } + cd_attributes = scstr.pcd_attributes; + cd_uid = Uid.mk ~current_unit:(Env.get_unit_name ()) } in tcstr, cstr in @@ -495,6 +498,7 @@ let transl_declaration env sdecl id = type_attributes = sdecl.ptype_attributes; type_immediate = false; type_unboxed = unboxed_status; + type_uid = uid; } in (* Check constraints *) @@ -905,38 +909,38 @@ let transl_type_decl env rec_flag sdecl_list = (* Create identifiers. *) let scope = Ctype.create_scope () in - let id_list = - List.map (fun sdecl -> Ident.create_scoped ~scope sdecl.ptype_name.txt) - sdecl_list + let ids_list = + List.map (fun sdecl -> + Ident.create_scoped ~scope sdecl.ptype_name.txt, + Uid.mk ~current_unit:(Env.get_unit_name ()) + ) sdecl_list in Ctype.begin_def(); (* Enter types. *) let temp_env = - List.fold_left2 (enter_type rec_flag) env sdecl_list id_list in + List.fold_left2 (enter_type rec_flag) env sdecl_list ids_list in (* Translate each declaration. *) let current_slot = ref None in let warn_unused = Warnings.is_active (Warnings.Unused_type_declaration "") in - let id_slots id = + let ids_slots (id, _uid as ids) = match rec_flag with | Asttypes.Recursive when warn_unused -> (* See typecore.ml for a description of the algorithm used to detect unused declarations in a set of recursive definitions. *) let slot = ref [] in let td = Env.find_type (Path.Pident id) temp_env in - let name = Ident.name id in Env.set_type_used_callback - name td + td (fun old_callback -> match !current_slot with - | Some slot -> slot := (name, td) :: !slot + | Some slot -> slot := td.type_uid :: !slot | None -> - List.iter (fun (name, d) -> Env.mark_type_used name d) - (get_ref slot); + List.iter Env.mark_type_used (get_ref slot); old_callback () ); - id, Some slot + ids, Some slot | Asttypes.Recursive | Asttypes.Nonrecursive -> - id, None + ids, None in let transl_declaration name_sdecl (id, slot) = current_slot := slot; @@ -945,7 +949,7 @@ let transl_type_decl env rec_flag sdecl_list = (fun () -> transl_declaration temp_env name_sdecl id) in let tdecls = - List.map2 transl_declaration sdecl_list (List.map id_slots id_list) in + List.map2 transl_declaration sdecl_list (List.map ids_slots ids_list) in let decls = List.map (fun tdecl -> (tdecl.typ_id, tdecl.typ_type)) tdecls in current_slot := None; @@ -958,16 +962,16 @@ let transl_type_decl env rec_flag sdecl_list = | Asttypes.Nonrecursive -> () | Asttypes.Recursive -> List.iter2 - (fun id sdecl -> update_type temp_env new_env id sdecl.ptype_loc) - id_list sdecl_list + (fun (id, _) sdecl -> update_type temp_env new_env id sdecl.ptype_loc) + ids_list sdecl_list end; (* Generalize type declarations. *) Ctype.end_def(); List.iter (fun (_, decl) -> generalize_decl decl) decls; (* Check for ill-formed abbrevs *) let id_loc_list = - List.map2 (fun id sdecl -> (id, sdecl.ptype_loc)) - id_list sdecl_list + List.map2 (fun (id, _) sdecl -> (id, sdecl.ptype_loc)) + ids_list sdecl_list in List.iter (fun (id, decl) -> check_well_founded_manifest new_env (List.assoc id id_loc_list) @@ -1121,7 +1125,9 @@ let transl_extension_constructor env type_path type_params ext_ret_type = ret_type; ext_private = priv; Types.ext_loc = sext.pext_loc; - Types.ext_attributes = sext.pext_attributes; } + Types.ext_attributes = sext.pext_attributes; + ext_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); + } in { ext_id = id; ext_name = sext.pext_name; @@ -1385,7 +1391,9 @@ let transl_value_decl env loc valdecl = match valdecl.pval_prim with [] when Env.is_in_signature env -> { val_type = ty; val_kind = Val_reg; Types.val_loc = loc; - val_attributes = valdecl.pval_attributes } + val_attributes = valdecl.pval_attributes; + val_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); + } | [] -> raise (Error(valdecl.pval_loc, Val_in_structure)) | _ -> @@ -1413,7 +1421,9 @@ let transl_value_decl env loc valdecl = then raise(Error(valdecl.pval_type.ptyp_loc, Missing_native_external)); check_unboxable env loc ty; { val_type = ty; val_kind = Val_prim prim; Types.val_loc = loc; - val_attributes = valdecl.pval_attributes } + val_attributes = valdecl.pval_attributes; + val_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); + } in let (id, newenv) = Env.enter_value valdecl.pval_name.txt v env @@ -1438,7 +1448,7 @@ let transl_value_decl env loc valdecl = (* Translate a "with" constraint -- much simplified version of transl_type_decl. *) let transl_with_constraint env id row_path orig_decl sdecl = - Env.mark_type_used (Ident.name id) orig_decl; + Env.mark_type_used orig_decl.type_uid; reset_type_variables(); Ctype.begin_def(); let tparams = make_params env sdecl.ptype_params in @@ -1494,6 +1504,7 @@ let transl_with_constraint env id row_path orig_decl sdecl = type_attributes = sdecl.ptype_attributes; type_immediate = false; type_unboxed; + type_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); } in begin match row_path with None -> () @@ -1546,6 +1557,7 @@ let abstract_type_decl arity = type_attributes = []; type_immediate = false; type_unboxed = unboxed_false_default_false; + type_uid = Uid.internal_not_actually_unique; } in Ctype.end_def(); generalize_decl decl; diff --git a/typing/typedtree.mli b/typing/typedtree.mli index 674512210a..af9b324fdf 100644 --- a/typing/typedtree.mli +++ b/typing/typedtree.mli @@ -22,7 +22,6 @@ *) open Asttypes -open Types (* Value expressions for the core language *) @@ -39,7 +38,7 @@ type pattern = { pat_desc: pattern_desc; pat_loc: Location.t; pat_extra : (pat_extra * Location.t * attributes) list; - pat_type: type_expr; + pat_type: Types.type_expr; mutable pat_env: Env.t; pat_attributes: attributes; } @@ -77,19 +76,19 @@ and pattern_desc = Invariant: n >= 2 *) | Tpat_construct of - Longident.t loc * constructor_description * pattern list + Longident.t loc * Types.constructor_description * pattern list (** C [] C P [P] C (P1, ..., Pn) [P1; ...; Pn] *) - | Tpat_variant of label * pattern option * row_desc ref + | Tpat_variant of label * pattern option * Types.row_desc ref (** `A (None) `A P (Some P) See {!Types.row_desc} for an explanation of the last parameter. *) | Tpat_record of - (Longident.t loc * label_description * pattern) list * + (Longident.t loc * Types.label_description * pattern) list * closed_flag (** { l1=P1; ...; ln=Pn } (flag = Closed) { l1=P1; ...; ln=Pn; _} (flag = Open) @@ -98,7 +97,7 @@ and pattern_desc = *) | Tpat_array of pattern list (** [| P1; ...; Pn |] *) - | Tpat_or of pattern * pattern * row_desc option + | Tpat_or of pattern * pattern * Types.row_desc option (** P1 | P2 [row_desc] = [Some _] when translating [Ppat_type _], @@ -113,7 +112,7 @@ and expression = { exp_desc: expression_desc; exp_loc: Location.t; exp_extra: (exp_extra * Location.t * attributes) list; - exp_type: type_expr; + exp_type: Types.type_expr; exp_env: Env.t; exp_attributes: attributes; } @@ -183,7 +182,7 @@ and expression_desc = | Texp_tuple of expression list (** (E1, ..., EN) *) | Texp_construct of - Longident.t loc * constructor_description * expression list + Longident.t loc * Types.constructor_description * expression list (** C [] C E [E] C (E1, ..., En) [E1;...;En] @@ -205,9 +204,9 @@ and expression_desc = { fields = [| l1, Kept t1; l2 Override P2 |]; representation; extended_expression = Some E0 } *) - | Texp_field of expression * Longident.t loc * label_description + | Texp_field of expression * Longident.t loc * Types.label_description | Texp_setfield of - expression * Longident.t loc * label_description * expression + expression * Longident.t loc * Types.label_description * expression | Texp_array of expression list | Texp_ifthenelse of expression * expression * expression option | Texp_sequence of expression * expression @@ -288,7 +287,7 @@ and class_expr_desc = | Tcl_let of rec_flag * value_binding list * (Ident.t * expression) list * class_expr | Tcl_constraint of - class_expr * class_type option * string list * string list * Concr.t + class_expr * class_type option * string list * string list * Types.Concr.t (* Visible instance variables, methods and concrete methods *) | Tcl_open of open_description * class_expr @@ -297,7 +296,7 @@ and class_structure = cstr_self: pattern; cstr_fields: class_field list; cstr_type: Types.class_signature; - cstr_meths: Ident.t Meths.t; + cstr_meths: Ident.t Types.Meths.t; } and class_field = @@ -387,7 +386,7 @@ and module_binding = { mb_id: Ident.t option; mb_name: string option loc; - mb_presence: module_presence; + mb_presence: Types.module_presence; mb_expr: module_expr; mb_attributes: attributes; mb_loc: Location.t; @@ -428,7 +427,7 @@ and module_type_desc = and primitive_coercion = { pc_desc: Primitive.description; - pc_type: type_expr; + pc_type: Types.type_expr; pc_env: Env.t; pc_loc : Location.t; } @@ -464,7 +463,7 @@ and module_declaration = { md_id: Ident.t option; md_name: string option loc; - md_presence: module_presence; + md_presence: Types.module_presence; md_type: module_type; md_attributes: attributes; md_loc: Location.t; @@ -525,7 +524,7 @@ and with_constraint = and core_type = { mutable ctyp_desc : core_type_desc; (** mutable because of [Typeclass.declare_method] *) - mutable ctyp_type : type_expr; + mutable ctyp_type : Types.type_expr; (** mutable because of [Typeclass.declare_method] *) ctyp_env : Env.t; (* BINANNOT ADDED *) ctyp_loc : Location.t; @@ -725,7 +724,7 @@ val let_bound_idents: value_binding list -> Ident.t list val rev_let_bound_idents: value_binding list -> Ident.t list val let_bound_idents_with_loc: - value_binding list -> (Ident.t * string loc * type_expr) list + value_binding list -> (Ident.t * string loc * Types.type_expr) list (** Alpha conversion of patterns *) val alpha_pat: (Ident.t * Ident.t) list -> pattern -> pattern @@ -735,7 +734,7 @@ val mkloc: 'a -> Location.t -> 'a Asttypes.loc val pat_bound_idents: pattern -> Ident.t list val pat_bound_idents_full: - pattern -> (Ident.t * string loc * type_expr) list + pattern -> (Ident.t * string loc * Types.type_expr) list (** Splits an or pattern into its value (left) and exception (right) parts. *) val split_pattern : pattern -> pattern option * pattern option diff --git a/typing/typemod.ml b/typing/typemod.ml index 90fd6a5d96..2790bdbcc2 100644 --- a/typing/typemod.ml +++ b/typing/typemod.ml @@ -493,6 +493,7 @@ let merge_constraint initial_env remove_aliases loc sg constr = type_attributes = []; type_immediate = false; type_unboxed = unboxed_false_default_false; + type_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); } and id_row = Ident.create_local (s^"#row") in let initial_env = @@ -736,6 +737,7 @@ and approx_module_declaration env pmd = Types.md_type = approx_modtype env pmd.pmd_type; md_attributes = pmd.pmd_attributes; md_loc = pmd.pmd_loc; + md_uid = Uid.internal_not_actually_unique; } and approx_sig env ssg = @@ -838,6 +840,7 @@ and approx_modtype_info env sinfo = mtd_type = Option.map (approx_modtype env) sinfo.pmtd_type; mtd_attributes = sinfo.pmtd_attributes; mtd_loc = sinfo.pmtd_loc; + mtd_uid = Uid.internal_not_actually_unique; } let approx_modtype env smty = @@ -1151,6 +1154,7 @@ and transl_modtype_aux env smty = { md_type = arg.mty_type; md_attributes = []; md_loc = param.loc; + md_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); } in Env.enter_module_declaration ~scope ~arg:true name Mp_present @@ -1288,6 +1292,7 @@ and transl_signature env sg = md_type=tmty.mty_type; md_attributes=pmd.pmd_attributes; md_loc=pmd.pmd_loc; + md_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); } in let id, newenv = @@ -1323,7 +1328,9 @@ and transl_signature env sg = else { md_type = Mty_alias path; md_attributes = pms.pms_attributes; - md_loc = pms.pms_loc } + md_loc = pms.pms_loc; + md_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); + } in let pres = match md.md_type with @@ -1349,21 +1356,22 @@ and transl_signature env sg = let (tdecls, newenv) = transl_recmodule_modtypes env sdecls in let decls = - List.filter_map (fun md -> + List.filter_map (fun (md, uid) -> match md.md_id with | None -> None - | Some id -> Some (id, md) + | Some id -> Some (id, md, uid) ) tdecls in - List.iter - (fun (id, md) -> Signature_names.check_module names md.md_loc id) - decls; + List.iter (fun (id, md, _) -> + Signature_names.check_module names md.md_loc id + ) decls; let (trem, rem, final_env) = transl_sig newenv srem in - mksig (Tsig_recmodule tdecls) env loc :: trem, - map_rec (fun rs (id, md) -> + mksig (Tsig_recmodule (List.map fst tdecls)) env loc :: trem, + map_rec (fun rs (id, md, uid) -> let d = {Types.md_type = md.md_type.mty_type; md_attributes = md.md_attributes; md_loc = md.md_loc; + md_uid = uid; } in Sig_module(id, Mp_present, d, rs, Exported)) decls rem, @@ -1493,6 +1501,7 @@ and transl_modtype_decl_aux names env Types.mtd_type=Option.map (fun t -> t.mty_type) tmty; mtd_attributes=pmtd_attributes; mtd_loc=pmtd_loc; + mtd_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); } in let scope = Ctype.create_scope () in @@ -1539,7 +1548,8 @@ and transl_recmodule_modtypes env sdecls = Option.map (fun id -> (id, Types.{md_type = mty.mty_type; md_loc = mty.mty_loc; - md_attributes = mty.mty_attributes}) + md_attributes = mty.mty_attributes; + md_uid = Uid.internal_not_actually_unique; }) ) id) in let scope = Ctype.create_scope () in @@ -1579,13 +1589,15 @@ and transl_recmodule_modtypes env sdecls = let env2 = make_env2 dcl2 in check_recmod_typedecls env2 (map_mtys dcl2); let dcl2 = - List.map2 - (fun pmd (id, id_loc, mty) -> + List.map2 (fun pmd (id, id_loc, mty) -> + let md = {md_id=id; md_name=id_loc; md_type=mty; md_presence=Mp_present; md_loc=pmd.pmd_loc; - md_attributes=pmd.pmd_attributes}) - sdecls dcl2 + md_attributes=pmd.pmd_attributes} + in + md, Uid.mk ~current_unit:(Env.get_unit_name ()) + ) sdecls dcl2 in (dcl2, env2) @@ -1711,7 +1723,7 @@ let check_recmodule_inclusion env bindings = (* Generate fresh names Y_i for the rec. bound module idents X_i *) let bindings1 = List.map - (fun (id, _name, _mty_decl, _modl, mty_actual, _attrs, _loc) -> + (fun (id, _name, _mty_decl, _modl, mty_actual, _attrs, _loc, _uid) -> let ids = Option.map (fun id -> (id, Ident.create_scoped ~scope (Ident.name id))) id @@ -1746,7 +1758,8 @@ let check_recmodule_inclusion env bindings = end else begin (* Base case: check inclusion of s(mty_actual) in s(mty_decl) and insert coercion if needed *) - let check_inclusion (id, name, mty_decl, modl, mty_actual, attrs, loc) = + let check_inclusion + (id, name, mty_decl, modl, mty_actual, attrs, loc, uid) = let mty_decl' = Subst.modtype (Rescope scope) s mty_decl.mty_type and mty_actual' = subst_and_strengthen env scope s id mty_actual in let coercion = @@ -1762,14 +1775,17 @@ let check_recmodule_inclusion env bindings = mod_loc = modl.mod_loc; mod_attributes = []; } in - { - mb_id = id; - mb_name = name; - mb_presence = Mp_present; - mb_expr = modl'; - mb_attributes = attrs; - mb_loc = loc; - } + let mb = + { + mb_id = id; + mb_name = name; + mb_presence = Mp_present; + mb_expr = modl'; + mb_attributes = attrs; + mb_loc = loc; + } + in + mb, uid in List.map check_inclusion bindings end @@ -1912,6 +1928,7 @@ and type_module_aux ~alias sttn funct_body anchor env smod = { md_type = mty.mty_type; md_attributes = []; md_loc = param.loc; + md_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); } in let id, newenv = @@ -2206,10 +2223,12 @@ and type_structure ?(toplevel = false) funct_body anchor env sstr scope = | Mty_alias _ -> Mp_absent | _ -> Mp_present in + let md_uid = Uid.mk ~current_unit:(Env.get_unit_name ()) in let md = { md_type = enrich_module_type anchor name.txt modl.mod_type env; md_attributes = attrs; md_loc = pmb_loc; + md_uid; } in (*prerr_endline (Ident.unique_toplevel_name id);*) @@ -2225,6 +2244,7 @@ and type_structure ?(toplevel = false) funct_body anchor env sstr scope = {md_type = modl.mod_type; md_attributes = attrs; md_loc = pmb_loc; + md_uid; }, Trec_not, Exported)] in Tstr_module {mb_id=id; mb_name=name; mb_expr=modl; @@ -2254,12 +2274,12 @@ and type_structure ?(toplevel = false) funct_body anchor env sstr scope = pmd_attributes=attrs; pmd_loc=loc}) sbind ) in List.iter - (fun md -> + (fun (md, _) -> Option.iter Signature_names.(check_module names md.md_loc) md.md_id) decls; let bindings1 = List.map2 - (fun {md_id=id; md_type=mty} (name, _, smodl, attrs, loc) -> + (fun ({md_id=id; md_type=mty}, uid) (name, _, smodl, attrs, loc) -> let modl = Builtin_attributes.warning_scope attrs (fun () -> @@ -2270,11 +2290,11 @@ and type_structure ?(toplevel = false) funct_body anchor env sstr scope = let mty' = enrich_module_type anchor name.txt modl.mod_type newenv in - (id, name, mty, modl, mty', attrs, loc)) + (id, name, mty, modl, mty', attrs, loc, uid)) decls sbind in let newenv = (* allow aliasing recursive modules from outside *) List.fold_left - (fun env md -> + (fun env (md, uid) -> match md.md_id with | None -> env | Some id -> @@ -2283,6 +2303,7 @@ and type_structure ?(toplevel = false) funct_body anchor env sstr scope = md_type = md.md_type.mty_type; md_attributes = md.md_attributes; md_loc = md.md_loc; + md_uid = uid; } in Env.add_module_declaration ~check:true @@ -2293,15 +2314,17 @@ and type_structure ?(toplevel = false) funct_body anchor env sstr scope = let bindings2 = check_recmodule_inclusion newenv bindings1 in let mbs = - List.filter_map (fun mb -> Option.map (fun id -> id, mb) mb.mb_id) - bindings2 + List.filter_map (fun (mb, uid) -> + Option.map (fun id -> id, mb, uid) mb.mb_id + ) bindings2 in - Tstr_recmodule bindings2, - map_rec (fun rs (id, mb) -> + Tstr_recmodule (List.map fst bindings2), + map_rec (fun rs (id, mb, uid) -> Sig_module(id, Mp_present, { md_type=mb.mb_expr.mod_type; md_attributes=mb.mb_attributes; md_loc=mb.mb_loc; + md_uid = uid; }, rs, Exported)) mbs [], newenv @@ -2645,7 +2668,9 @@ let package_signatures units = let md = { md_type=Mty_signature sg; md_attributes=[]; - md_loc=Location.none; } + md_loc=Location.none; + md_uid = Uid.mk ~current_unit:(Env.get_unit_name ()); + } in Sig_module(newid, Mp_present, md, Trec_not, Exported)) units_with_ids diff --git a/typing/types.ml b/typing/types.ml index 51c404bf8e..85b48eee9b 100644 --- a/typing/types.ml +++ b/typing/types.ml @@ -79,6 +79,38 @@ module TypeOps = struct let equal t1 t2 = t1 == t2 end +(* *) + +module Uid = struct + type t = + | Compilation_unit of string + | Item of { comp_unit: string; id: int } + | Internal + | Predef of string + + let mk = + let id = ref (-1) in + fun ~current_unit -> + incr id; + Item { comp_unit = current_unit; id = !id } + + let of_compilation_unit_id id = + if not (Ident.persistent id) then + Misc.fatal_errorf "Types.Uid.of_compilation_unit_id %S" (Ident.name id); + Compilation_unit (Ident.name id) + + let of_predef_id id = + if not (Ident.is_predef id) then + Misc.fatal_errorf "Types.Uid.of_predef_id %S" (Ident.name id); + Predef (Ident.name id) + + let internal_not_actually_unique = Internal + + let for_actual_declaration = function + | Item _ -> true + | _ -> false +end + (* Maps of methods and instance variables *) module Meths = Misc.Stdlib.String.Map @@ -91,7 +123,8 @@ type value_description = val_kind: value_kind; val_loc: Location.t; val_attributes: Parsetree.attributes; - } + val_uid: Uid.t; + } and value_kind = Val_reg (* Regular value *) @@ -151,6 +184,7 @@ type type_declaration = type_attributes: Parsetree.attributes; type_immediate: bool; type_unboxed: unboxed_status; + type_uid: Uid.t; } and type_kind = @@ -173,6 +207,7 @@ and label_declaration = ld_type: type_expr; ld_loc: Location.t; ld_attributes: Parsetree.attributes; + ld_uid: Uid.t; } and constructor_declaration = @@ -182,6 +217,7 @@ and constructor_declaration = cd_res: type_expr option; cd_loc: Location.t; cd_attributes: Parsetree.attributes; + cd_uid: Uid.t; } and constructor_arguments = @@ -200,13 +236,15 @@ let unboxed_true_default_false = {unboxed = true; default = false} let unboxed_true_default_true = {unboxed = true; default = true} type extension_constructor = - { ext_type_path: Path.t; - ext_type_params: type_expr list; - ext_args: constructor_arguments; - ext_ret_type: type_expr option; - ext_private: private_flag; - ext_loc: Location.t; - ext_attributes: Parsetree.attributes; } + { ext_type_path: Path.t; + ext_type_params: type_expr list; + ext_args: constructor_arguments; + ext_ret_type: type_expr option; + ext_private: private_flag; + ext_loc: Location.t; + ext_attributes: Parsetree.attributes; + ext_uid: Uid.t; + } and type_transparence = Type_public (* unrestricted expansion *) @@ -237,6 +275,7 @@ type class_declaration = cty_variance: Variance.t list; cty_loc: Location.t; cty_attributes: Parsetree.attributes; + cty_uid: Uid.t; } type class_type_declaration = @@ -246,6 +285,7 @@ type class_type_declaration = clty_variance: Variance.t list; clty_loc: Location.t; clty_attributes: Parsetree.attributes; + clty_uid: Uid.t; } (* Type expressions for the module language *) @@ -285,6 +325,7 @@ and module_declaration = md_type: module_type; md_attributes: Parsetree.attributes; md_loc: Location.t; + md_uid: Uid.t; } and modtype_declaration = @@ -292,6 +333,7 @@ and modtype_declaration = mtd_type: module_type option; (* Note: abstract *) mtd_attributes: Parsetree.attributes; mtd_loc: Location.t; + mtd_uid: Uid.t; } and rec_status = @@ -323,6 +365,7 @@ type constructor_description = cstr_loc: Location.t; cstr_attributes: Parsetree.attributes; cstr_inlined: type_declaration option; + cstr_uid: Uid.t; } and constructor_tag = @@ -356,6 +399,7 @@ type label_description = lbl_private: private_flag; (* Read-only field? *) lbl_loc: Location.t; lbl_attributes: Parsetree.attributes; + lbl_uid: Uid.t; } let rec bound_value_identifiers = function diff --git a/typing/types.mli b/typing/types.mli index f5e75a9a44..38263e743f 100644 --- a/typing/types.mli +++ b/typing/types.mli @@ -240,6 +240,19 @@ module TypeOps : sig val hash : t -> int end +(* *) + +module Uid : sig + type t + + val mk : current_unit:string -> t + val of_compilation_unit_id : Ident.t -> t + val of_predef_id : Ident.t -> t + val internal_not_actually_unique : t + + val for_actual_declaration : t -> bool +end + (* Maps of methods and instance variables *) module Meths : Map.S with type key = string @@ -252,7 +265,8 @@ type value_description = val_kind: value_kind; val_loc: Location.t; val_attributes: Parsetree.attributes; - } + val_uid: Uid.t; + } and value_kind = Val_reg (* Regular value *) @@ -301,6 +315,7 @@ type type_declaration = type_attributes: Parsetree.attributes; type_immediate: bool; (* true iff type should not be a pointer *) type_unboxed: unboxed_status; + type_uid: Uid.t; } and type_kind = @@ -323,6 +338,7 @@ and label_declaration = ld_type: type_expr; ld_loc: Location.t; ld_attributes: Parsetree.attributes; + ld_uid: Uid.t; } and constructor_declaration = @@ -332,6 +348,7 @@ and constructor_declaration = cd_res: type_expr option; cd_loc: Location.t; cd_attributes: Parsetree.attributes; + cd_uid: Uid.t; } and constructor_arguments = @@ -353,15 +370,16 @@ val unboxed_true_default_false : unboxed_status val unboxed_true_default_true : unboxed_status type extension_constructor = - { - ext_type_path: Path.t; - ext_type_params: type_expr list; - ext_args: constructor_arguments; - ext_ret_type: type_expr option; - ext_private: private_flag; - ext_loc: Location.t; - ext_attributes: Parsetree.attributes; - } + { + ext_type_path: Path.t; + ext_type_params: type_expr list; + ext_args: constructor_arguments; + ext_ret_type: type_expr option; + ext_private: private_flag; + ext_loc: Location.t; + ext_attributes: Parsetree.attributes; + ext_uid: Uid.t; + } and type_transparence = Type_public (* unrestricted expansion *) @@ -392,6 +410,7 @@ type class_declaration = cty_variance: Variance.t list; cty_loc: Location.t; cty_attributes: Parsetree.attributes; + cty_uid: Uid.t; } type class_type_declaration = @@ -401,6 +420,7 @@ type class_type_declaration = clty_variance: Variance.t list; clty_loc: Location.t; clty_attributes: Parsetree.attributes; + clty_uid: Uid.t; } (* Type expressions for the module language *) @@ -440,6 +460,7 @@ and module_declaration = md_type: module_type; md_attributes: Parsetree.attributes; md_loc: Location.t; + md_uid: Uid.t; } and modtype_declaration = @@ -447,6 +468,7 @@ and modtype_declaration = mtd_type: module_type option; (* None: abstract *) mtd_attributes: Parsetree.attributes; mtd_loc: Location.t; + mtd_uid: Uid.t; } and rec_status = @@ -478,6 +500,7 @@ type constructor_description = cstr_loc: Location.t; cstr_attributes: Parsetree.attributes; cstr_inlined: type_declaration option; + cstr_uid: Uid.t; } and constructor_tag = @@ -505,6 +528,7 @@ type label_description = lbl_private: private_flag; (* Read-only field? *) lbl_loc: Location.t; lbl_attributes: Parsetree.attributes; + lbl_uid: Uid.t; } (** Extracts the list of "value" identifiers bound by a signature. |