@@ -183,6 +183,8 @@ let iterator_with_env env =
183
183
let super = Btype. type_iterators in
184
184
env, { super with
185
185
Btype. it_signature = (fun self sg ->
186
+ (* add all items to the env before recursing down, to handle recursive
187
+ definitions *)
186
188
let env_before = ! env in
187
189
List. iter (fun i -> env := Env. add_item i ! env) sg;
188
190
super.Btype. it_signature self sg;
@@ -220,21 +222,26 @@ let retype_applicative_functor_type ~loc env funct arg =
220
222
- aliases: module A = M still makes sense but it doesn't mean the same thing
221
223
anymore, so it's forbidden until it's clear what we should do with it.
222
224
This function would be called with M.N.t and N.t to check for these uses. *)
223
- let check_usage_of_path_of_substituted_item path env signature ~loc ~lid =
225
+ let check_usage_of_path_of_substituted_item paths env signature ~loc ~lid =
224
226
let iterator =
225
227
let env, super = iterator_with_env env in
226
228
{ super with
227
229
Btype. it_signature_item = (fun self -> function
228
230
| Sig_module (id, { md_type = Mty_alias (_, aliased_path); _ }, _)
229
- when path_is_strict_prefix path ~prefix: aliased_path ->
231
+ when List. exists
232
+ (fun path -> path_is_strict_prefix path ~prefix: aliased_path)
233
+ paths
234
+ ->
230
235
let e = With_changes_module_alias (lid.txt, id, aliased_path) in
231
236
raise(Error (loc, ! env, e))
232
237
| sig_item ->
233
238
super.Btype. it_signature_item self sig_item
234
239
);
235
240
Btype. it_path = (fun referenced_path ->
236
241
iter_path_apply referenced_path ~f: (fun funct arg ->
237
- if path_is_strict_prefix path ~prefix: arg
242
+ if List. exists
243
+ (fun path -> path_is_strict_prefix path ~prefix: arg)
244
+ paths
238
245
then
239
246
let env = ! env in
240
247
try retype_applicative_functor_type ~loc env funct arg
@@ -378,9 +385,6 @@ let merge_constraint initial_env loc sg constr =
378
385
let path = path_concat id path in
379
386
real_ids := path :: ! real_ids;
380
387
let item = Sig_module (id, {md with md_type= Mty_signature newsg}, rs) in
381
- if destructive_substitution then
382
- check_usage_of_path_of_substituted_item
383
- path (Env. add_item item env) rem ~loc ~lid ;
384
388
(path, lid, tcstr),
385
389
item :: rem
386
390
| (item :: rem , _ , _ ) ->
@@ -391,6 +395,19 @@ let merge_constraint initial_env loc sg constr =
391
395
try
392
396
let names = Longident. flatten lid.txt in
393
397
let (tcstr, sg) = merge initial_env sg names None in
398
+ if destructive_substitution then (
399
+ match List. rev ! real_ids with
400
+ | [] -> assert false
401
+ | last :: rest ->
402
+ (* The last item is the one that's removed. We don't need to check how
403
+ it's used since it's replaced by a more specific type/module. *)
404
+ assert (match last with Pident _ -> true | _ -> false );
405
+ match rest with
406
+ | [] -> ()
407
+ | _ :: _ ->
408
+ check_usage_of_path_of_substituted_item
409
+ rest initial_env sg ~loc ~lid ;
410
+ );
394
411
let sg =
395
412
match tcstr with
396
413
| (_ , _ , Twith_typesubst tdecl ) ->
0 commit comments