Skip to content

Commit a811fe0

Browse files
committed
Merge changes in Merlin
1 parent 24742d0 commit a811fe0

File tree

6 files changed

+310
-97
lines changed

6 files changed

+310
-97
lines changed

src/ocaml/typing/includemod.ml

+58-39
Original file line numberDiff line numberDiff line change
@@ -452,21 +452,35 @@ and try_modtypes ~in_eq ~loc env ~mark subst mty1 mty2 orig_shape =
452452
functor_param ~in_eq ~loc env ~mark:(negate_mark mark)
453453
subst param1 param2
454454
in
455-
(* Using a fresh variable with a placeholder uid here is fine: users will
456-
never try to jump to the definition of that variable.
457-
If they try to jump to the parameter from inside the functor, they will
458-
use the variable shape that is stored in the local environment. *)
459-
let var, shape_var = Shape.fresh_var Uid.internal_not_actually_unique in
460-
let cc_res =
461-
let res_shape = Shape.app orig_shape ~arg:shape_var in
462-
modtypes ~in_eq ~loc env ~mark subst res1 res2 res_shape
455+
let var, res_shape =
456+
match Shape.decompose_abs orig_shape with
457+
| Some (var, res_shape) -> var, res_shape
458+
| None ->
459+
(* Using a fresh variable with a placeholder uid here is fine: users
460+
will never try to jump to the definition of that variable.
461+
If they try to jump to the parameter from inside the functor,
462+
they will use the variable shape that is stored in the local
463+
environment. *)
464+
let var, shape_var =
465+
Shape.fresh_var Uid.internal_not_actually_unique
466+
in
467+
var, Shape.app orig_shape ~arg:shape_var
463468
in
469+
let cc_res = modtypes ~in_eq ~loc env ~mark subst res1 res2 res_shape in
464470
begin match cc_arg, cc_res with
465-
| Ok Tcoerce_none, Ok (Tcoerce_none, res_shape) ->
466-
let final_shape = Shape.abs var res_shape in
471+
| Ok Tcoerce_none, Ok (Tcoerce_none, final_res_shape) ->
472+
let final_shape =
473+
if final_res_shape == res_shape
474+
then orig_shape
475+
else Shape.abs var final_res_shape
476+
in
467477
Ok (Tcoerce_none, final_shape)
468-
| Ok cc_arg, Ok (cc_res, res_shape) ->
469-
let final_shape = Shape.abs var res_shape in
478+
| Ok cc_arg, Ok (cc_res, final_res_shape) ->
479+
let final_shape =
480+
if final_res_shape == res_shape
481+
then orig_shape
482+
else Shape.abs var final_res_shape
483+
in
470484
Ok (Tcoerce_functor(cc_arg, cc_res), final_shape)
471485
| _, Error {Error.symptom = Error.Functor Error.Params res; _} ->
472486
let got_params, got_res = res.got in
@@ -562,33 +576,31 @@ and signatures ~in_eq ~loc env ~mark subst sig1 sig2 mod_shape =
562576
([], 0) sig1 in
563577
(* Build a table of the components of sig1, along with their positions.
564578
The table is indexed by kind and name of component *)
565-
let rec build_component_table pos tbl = function
566-
[] -> pos, tbl
567-
| (Sig_value (_, _, Hidden)
568-
|Sig_type (_, _, _, Hidden)
569-
|Sig_typext (_, _, _, Hidden)
570-
|Sig_module (_, _, _, _, Hidden)
571-
|Sig_modtype (_, _, Hidden)
572-
|Sig_class (_, _, _, Hidden)
573-
|Sig_class_type (_, _, _, Hidden)
574-
) as item :: rem ->
575-
let pos = if is_runtime_component item then pos + 1 else pos in
576-
build_component_table pos tbl rem (* do not pair private items. *)
579+
let rec build_component_table nb_exported pos tbl = function
580+
[] -> nb_exported, pos, tbl
577581
| item :: rem ->
578-
let (id, _loc, name) = item_ident_name item in
579582
let pos, nextpos =
580583
if is_runtime_component item then pos, pos + 1
581584
else -1, pos
582585
in
583-
build_component_table nextpos
584-
(FieldMap.add name (id, item, pos) tbl) rem in
585-
let len1, comps1 =
586-
build_component_table 0 FieldMap.empty sig1 in
587-
let len2 =
588-
List.fold_left
589-
(fun n i -> if is_runtime_component i then n + 1 else n)
590-
0
591-
sig2
586+
match item_visibility item with
587+
| Hidden ->
588+
(* do not pair private items. *)
589+
build_component_table nb_exported nextpos tbl rem
590+
| Exported ->
591+
let (id, _loc, name) = item_ident_name item in
592+
build_component_table (nb_exported + 1) nextpos
593+
(FieldMap.add name (id, item, pos) tbl) rem
594+
in
595+
let exported_len1, runtime_len1, comps1 =
596+
build_component_table 0 0 FieldMap.empty sig1
597+
in
598+
let exported_len2, runtime_len2 =
599+
List.fold_left (fun (el, rl) i ->
600+
let el = match item_visibility i with Hidden -> el | Exported -> el + 1 in
601+
let rl = if is_runtime_component i then rl + 1 else rl in
602+
el, rl
603+
) (0, 0) sig2
592604
in
593605
(* Pair each component of sig2 with a component of sig1,
594606
identifying the names along the way.
@@ -597,15 +609,19 @@ and signatures ~in_eq ~loc env ~mark subst sig1 sig2 mod_shape =
597609
and the coercion to be applied to it. *)
598610
let rec pair_components subst paired unpaired = function
599611
[] ->
600-
let oks, shape_map, errors =
612+
let oks, (shape_map, deep_modifications), errors =
601613
signature_components ~in_eq ~loc env ~mark new_env subst mod_shape
602614
Shape.Map.empty
603615
(List.rev paired)
604616
in
605617
begin match unpaired, errors, oks with
606618
| [], [], cc ->
607-
let shape = Shape.str ?uid:mod_shape.Shape.uid shape_map in
608-
if len1 = len2 then (* see PR#5098 *)
619+
let shape =
620+
if not deep_modifications && exported_len1 = exported_len2
621+
then mod_shape
622+
else Shape.str ?uid:mod_shape.Shape.uid shape_map
623+
in
624+
if runtime_len1 = runtime_len2 then (* see PR#5098 *)
609625
Ok (simplify_structure_coercion cc id_pos_list, shape)
610626
else
611627
Ok (Tcoerce_structure (cc, id_pos_list), shape)
@@ -655,8 +671,9 @@ and signatures ~in_eq ~loc env ~mark subst sig1 sig2 mod_shape =
655671
and signature_components ~in_eq ~loc old_env ~mark env subst
656672
orig_shape shape_map paired =
657673
match paired with
658-
| [] -> [], shape_map, []
674+
| [] -> [], (shape_map, false), []
659675
| (sigi1, sigi2, pos) :: rem ->
676+
let shape_modified = ref false in
660677
let id, item, shape_map, present_at_runtime =
661678
match sigi1, sigi2 with
662679
| Sig_value(id1, valdecl1, _) ,Sig_value(_id2, valdecl2, _) ->
@@ -695,6 +712,7 @@ and signature_components ~in_eq ~loc old_env ~mark env subst
695712
let item, shape_map =
696713
match item with
697714
| Ok (cc, shape) ->
715+
if shape != orig_shape then shape_modified := true;
698716
let mod_shape = Shape.set_uid_if_none shape mty1.md_uid in
699717
Ok cc, Shape.Map.add_module shape_map id1 mod_shape
700718
| Error diff ->
@@ -741,10 +759,11 @@ and signature_components ~in_eq ~loc old_env ~mark env subst
741759
| _ ->
742760
assert false
743761
in
744-
let oks, final_map, errors =
762+
let oks, (final_map, deep_modifications), errors =
745763
signature_components ~in_eq ~loc old_env ~mark env subst
746764
orig_shape shape_map rem
747765
in
766+
let final_map = final_map, deep_modifications || !shape_modified in
748767
match item with
749768
| Ok x when present_at_runtime -> (pos,x) :: oks, final_map, errors
750769
| Ok _ -> oks, final_map, errors

0 commit comments

Comments
 (0)