Skip to content

Commit edf310e

Browse files
committed
properly scope idents
- when including: the elements are rescoped to the current level (as well as being given a fresh stamp, which was already the case) - extension constructors idents cannot be local: they can be used as types when the constructor's argument is an inlined record. They must be given a scope - in check_recmod_inclusion: create a new scope at each iteration - when checking that type declarations inside recursive modules are well founded, we now take a generic instance of the declaration (this is reminiscent of what is done in Ctype.moregeneral)
1 parent 94b55c1 commit edf310e

File tree

6 files changed

+49
-7
lines changed

6 files changed

+49
-7
lines changed

typing/ctype.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,13 @@ let instance_declaration decl =
11921192
cleanup_types ();
11931193
decl
11941194

1195+
let generic_instance_declaration decl =
1196+
let old = !current_level in
1197+
current_level := generic_level;
1198+
let decl = instance_declaration decl in
1199+
current_level := old;
1200+
decl
1201+
11951202
let instance_class params cty =
11961203
let rec copy_class_type =
11971204
function

typing/ctype.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ val instance_parameterized_type_2:
130130
type_expr list -> type_expr list -> type_expr ->
131131
type_expr list * type_expr list * type_expr
132132
val instance_declaration: type_declaration -> type_declaration
133+
val generic_instance_declaration: type_declaration -> type_declaration
134+
(* Same as instance_declaration, but new nodes at generic_level *)
133135
val instance_class:
134136
type_expr list -> class_type -> type_expr list * class_type
135137
val instance_poly:

typing/subst.ml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ and signature s sg =
439439
(* ... then apply it to each signature component in turn *)
440440
List.map2 (signature_component s') sg new_idents
441441

442+
442443
and signature_component s comp newid =
443444
match comp with
444445
Sig_value(_id, d) ->
@@ -470,6 +471,33 @@ and modtype_declaration s decl =
470471
mtd_loc = loc s decl.mtd_loc;
471472
}
472473

474+
(* Same as [signature] except than instead of making the items local, we rescope
475+
them. *)
476+
let refresh_signature ~scope sg =
477+
let rec refresh_bound_idents s idents = function
478+
[] -> (List.rev idents, s)
479+
| Sig_type(id, _, _) :: sg ->
480+
let id' = Ident.create_scoped ~scope (Ident.name id) in
481+
refresh_bound_idents (add_type id (Pident id') s) (id' :: idents) sg
482+
| Sig_module(id, _, _) :: sg ->
483+
let id' = Ident.create_scoped ~scope (Ident.name id) in
484+
refresh_bound_idents (add_module id (Pident id') s) (id' :: idents) sg
485+
| Sig_modtype(id, _) :: sg ->
486+
let id' = Ident.create_scoped ~scope (Ident.name id) in
487+
refresh_bound_idents (add_modtype id (Mty_ident(Pident id')) s)
488+
(id' :: idents) sg
489+
| (Sig_class(id, _, _) | Sig_class_type(id, _, _)) :: sg ->
490+
(* cheat and pretend they are types cf. PR#6650 *)
491+
let id' = Ident.create_scoped ~scope (Ident.name id) in
492+
refresh_bound_idents (add_type id (Pident id') s) (id' :: idents) sg
493+
| (Sig_value(id, _) | Sig_typext(id, _, _)) :: sg ->
494+
let id' = Ident.create_scoped ~scope (Ident.name id) in
495+
refresh_bound_idents s (id' :: idents) sg
496+
in
497+
let (new_idents, s') = refresh_bound_idents identity [] sg in
498+
List.map2 (signature_component s') sg new_idents
499+
500+
473501
(* For every binding k |-> d of m1, add k |-> f d to m2
474502
and return resulting merged map. *)
475503

typing/subst.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ val modtype_declaration: t -> modtype_declaration -> modtype_declaration
6161
val module_declaration: t -> module_declaration -> module_declaration
6262
val class_signature: t -> class_signature -> class_signature
6363

64+
val refresh_signature: scope:int -> signature -> signature
65+
6466
(* Composition of substitutions:
6567
apply (compose s1 s2) x = apply s2 (apply s1 x) *)
6668
val compose: t -> t -> t

typing/typedecl.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,7 @@ let check_well_founded_decl env loc path decl to_check =
775775
let it =
776776
{type_iterators with
777777
it_type_expr = (fun _ -> check_well_founded env loc path to_check)} in
778-
it.it_type_declaration it (Ctype.instance_declaration decl)
778+
it.it_type_declaration it (Ctype.generic_instance_declaration decl)
779779

780780
(* Check for ill-defined abbrevs *)
781781

@@ -1411,7 +1411,8 @@ let transl_type_decl env rec_flag sdecl_list =
14111411

14121412
let transl_extension_constructor env type_path type_params
14131413
typext_params priv sext =
1414-
let id = Ident.create_local sext.pext_name.txt in
1414+
let scope = Ctype.get_current_level () in
1415+
let id = Ident.create_scoped ~scope sext.pext_name.txt in
14151416
let args, ret_type, kind =
14161417
match sext.pext_kind with
14171418
Pext_decl(sargs, sret_type) ->

typing/typemod.ml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ and approx_sig env ssg =
742742
| Psig_include sincl ->
743743
let smty = sincl.pincl_mod in
744744
let mty = approx_modtype env smty in
745-
let sg = Subst.signature Subst.identity
745+
let sg = Subst.refresh_signature ~scope:(Ctype.get_current_level ())
746746
(extract_sig env smty.pmty_loc mty) in
747747
let newenv = Env.add_signature sg env in
748748
sg @ approx_sig newenv srem
@@ -1114,7 +1114,7 @@ and transl_signature env sg =
11141114
(fun () -> transl_modtype env smty)
11151115
in
11161116
let mty = tmty.mty_type in
1117-
let sg = Subst.signature Subst.identity
1117+
let sg = Subst.refresh_signature ~scope:(Ctype.get_current_level ())
11181118
(extract_sig env smty.pmty_loc mty) in
11191119
List.iter
11201120
(fun i -> check_sig_item names item.psig_loc i to_be_removed)
@@ -1403,11 +1403,13 @@ let check_recmodule_inclusion env bindings =
14031403
let rec check_incl first_time n env s =
14041404
if n > 0 then begin
14051405
(* Generate fresh names Y_i for the rec. bound module idents X_i *)
1406+
let scope = Ctype.get_current_level () in
14061407
let bindings1 =
14071408
List.map
1408-
(fun (id, _, _mty_decl, _modl, mty_actual, _attrs, _loc) ->
1409-
(id, Ident.rename id, mty_actual))
1409+
(fun (id, name, _mty_decl, _modl, mty_actual, _attrs, _loc) ->
1410+
(id, Ident.create_scoped ~scope name.txt, mty_actual))
14101411
bindings in
1412+
Ctype.init_def (scope + 1);
14111413
(* Enter the Y_i in the environment with their actual types substituted
14121414
by the input substitution s *)
14131415
let env' =
@@ -1953,7 +1955,7 @@ and type_structure ?(toplevel = false) funct_body anchor env sstr scope =
19531955
(fun () -> type_module true funct_body None env smodl)
19541956
in
19551957
(* Rename all identifiers bound by this signature to avoid clashes *)
1956-
let sg = Subst.signature Subst.identity
1958+
let sg = Subst.refresh_signature ~scope:(Ctype.get_current_level ())
19571959
(extract_sig_open env smodl.pmod_loc modl.mod_type) in
19581960
List.iter (fun item -> check_sig_item names loc item to_be_removed)
19591961
(List.rev sg);

0 commit comments

Comments
 (0)