summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ocamldoc/odoc_sig.ml7
-rw-r--r--parsing/ast_iterator.ml4
-rw-r--r--parsing/ast_mapper.ml4
-rw-r--r--parsing/depend.ml2
-rw-r--r--parsing/parsetree.mli4
-rw-r--r--parsing/pprintast.ml41
-rw-r--r--parsing/printast.ml8
-rw-r--r--typing/includemod.ml3
-rw-r--r--typing/includemod.mli3
-rw-r--r--typing/printtyped.ml4
-rw-r--r--typing/tast_iterator.ml3
-rw-r--r--typing/tast_mapper.ml4
-rw-r--r--typing/typedtree.ml3
-rw-r--r--typing/typedtree.mli2
-rw-r--r--typing/typemod.ml56
-rw-r--r--typing/untypeast.ml4
16 files changed, 122 insertions, 30 deletions
diff --git a/ocamldoc/odoc_sig.ml b/ocamldoc/odoc_sig.ml
index d52dee8930..529af8ef1c 100644
--- a/ocamldoc/odoc_sig.ml
+++ b/ocamldoc/odoc_sig.ml
@@ -451,11 +451,14 @@ module Analyser =
let erased_names_of_constraints constraints acc =
List.fold_right (fun constraint_ acc ->
match constraint_ with
- | Parsetree.Pwith_type _ | Parsetree.Pwith_module _ -> acc
+ | Parsetree.Pwith_type _ | Parsetree.Pwith_module _ | Parsetree.Pwith_module_type _ -> acc
| Parsetree.Pwith_typesubst (s, typedecl) ->
constraint_for_subitem acc s (fun s -> Parsetree.Pwith_typesubst (s, typedecl))
| Parsetree.Pwith_modsubst (s, modpath) ->
- constraint_for_subitem acc s (fun s -> Parsetree.Pwith_modsubst (s, modpath)))
+ constraint_for_subitem acc s (fun s -> Parsetree.Pwith_modsubst (s, modpath))
+ | Parsetree.Pwith_module_typesubst (s, modpath) ->
+ constraint_for_subitem acc s
+ (fun s -> Parsetree.Pwith_module_typesubst (s, modpath)))
constraints acc
let is_erased ident map =
diff --git a/parsing/ast_iterator.ml b/parsing/ast_iterator.ml
index 10d575123b..1cdb95310a 100644
--- a/parsing/ast_iterator.ml
+++ b/parsing/ast_iterator.ml
@@ -263,10 +263,14 @@ module MT = struct
iter_loc sub lid; sub.type_declaration sub d
| Pwith_module (lid, lid2) ->
iter_loc sub lid; iter_loc sub lid2
+ | Pwith_module_type (lid, mty) ->
+ iter_loc sub lid; iter_loc sub mty
| Pwith_typesubst (lid, d) ->
iter_loc sub lid; sub.type_declaration sub d
| Pwith_modsubst (s, lid) ->
iter_loc sub s; iter_loc sub lid
+ | Pwith_module_typesubst (lid, mty) ->
+ iter_loc sub lid; iter_loc sub mty
let iter_signature_item sub {psig_desc = desc; psig_loc = loc} =
sub.location sub loc;
diff --git a/parsing/ast_mapper.ml b/parsing/ast_mapper.ml
index d9a77c952f..720c16af34 100644
--- a/parsing/ast_mapper.ml
+++ b/parsing/ast_mapper.ml
@@ -293,10 +293,14 @@ module MT = struct
Pwith_type (map_loc sub lid, sub.type_declaration sub d)
| Pwith_module (lid, lid2) ->
Pwith_module (map_loc sub lid, map_loc sub lid2)
+ | Pwith_module_type (lid, mty) ->
+ Pwith_module_type (map_loc sub lid, map_loc sub mty)
| Pwith_typesubst (lid, d) ->
Pwith_typesubst (map_loc sub lid, sub.type_declaration sub d)
| Pwith_modsubst (s, lid) ->
Pwith_modsubst (map_loc sub s, map_loc sub lid)
+ | Pwith_module_typesubst (lid, mty) ->
+ Pwith_module_typesubst (map_loc sub lid, map_loc sub mty)
let map_signature_item sub {psig_desc = desc; psig_loc = loc} =
let open Sig in
diff --git a/parsing/depend.ml b/parsing/depend.ml
index d72bf63b35..f1a155c1ba 100644
--- a/parsing/depend.ml
+++ b/parsing/depend.ml
@@ -311,8 +311,10 @@ and add_modtype bv mty =
(function
| Pwith_type (_, td) -> add_type_declaration bv td
| Pwith_module (_, lid) -> add_module_path bv lid
+ | Pwith_module_type (_, l) -> add bv l
| Pwith_typesubst (_, td) -> add_type_declaration bv td
| Pwith_modsubst (_, lid) -> add_module_path bv lid
+ | Pwith_module_typesubst (_, l) -> add bv l
)
cstrl
| Pmty_typeof m -> add_module_expr bv m
diff --git a/parsing/parsetree.mli b/parsing/parsetree.mli
index 952920287a..8337c289b3 100644
--- a/parsing/parsetree.mli
+++ b/parsing/parsetree.mli
@@ -852,6 +852,10 @@ and with_constraint =
the name of the type_declaration. *)
| Pwith_module of Longident.t loc * Longident.t loc
(* with module X.Y = Z *)
+ | Pwith_module_type of Longident.t loc * Longident.t loc
+ (* with module type X.Y = Z *)
+ | Pwith_module_typesubst of Longident.t loc * Longident.t loc
+ (* with module type X.Y := Z *)
| Pwith_typesubst of Longident.t loc * type_declaration
(* with type X.t := ..., same format as [Pwith_type] *)
| Pwith_modsubst of Longident.t loc * Longident.t loc
diff --git a/parsing/pprintast.ml b/parsing/pprintast.ml
index aefd74c32c..29351cc02a 100644
--- a/parsing/pprintast.ml
+++ b/parsing/pprintast.ml
@@ -1059,26 +1059,33 @@ and module_type ctxt f x =
end
| Pmty_with (mt, []) -> module_type ctxt f mt
| Pmty_with (mt, l) ->
- let with_constraint f = function
- | Pwith_type (li, ({ptype_params= ls ;_} as td)) ->
- let ls = List.map fst ls in
- pp f "type@ %a %a =@ %a"
- (list (core_type ctxt) ~sep:"," ~first:"(" ~last:")")
- ls longident_loc li (type_declaration ctxt) td
- | Pwith_module (li, li2) ->
- pp f "module %a =@ %a" longident_loc li longident_loc li2;
- | Pwith_typesubst (li, ({ptype_params=ls;_} as td)) ->
- let ls = List.map fst ls in
- pp f "type@ %a %a :=@ %a"
- (list (core_type ctxt) ~sep:"," ~first:"(" ~last:")")
- ls longident_loc li
- (type_declaration ctxt) td
- | Pwith_modsubst (li, li2) ->
- pp f "module %a :=@ %a" longident_loc li longident_loc li2 in
pp f "@[<hov2>%a@ with@ %a@]"
- (module_type1 ctxt) mt (list with_constraint ~sep:"@ and@ ") l
+ (module_type1 ctxt) mt
+ (list (with_constraint ctxt) ~sep:"@ and@ ") l
| _ -> module_type1 ctxt f x
+and with_constraint ctxt f = function
+ | Pwith_type (li, ({ptype_params= ls ;_} as td)) ->
+ let ls = List.map fst ls in
+ pp f "type@ %a %a =@ %a"
+ (list (core_type ctxt) ~sep:"," ~first:"(" ~last:")")
+ ls longident_loc li (type_declaration ctxt) td
+ | Pwith_module (li, li2) ->
+ pp f "module %a =@ %a" longident_loc li longident_loc li2;
+ | Pwith_module_type (li, li2) ->
+ pp f "module type %a =@ %a" longident_loc li longident_loc li2
+ | Pwith_typesubst (li, ({ptype_params=ls;_} as td)) ->
+ let ls = List.map fst ls in
+ pp f "type@ %a %a :=@ %a"
+ (list (core_type ctxt) ~sep:"," ~first:"(" ~last:")")
+ ls longident_loc li
+ (type_declaration ctxt) td
+ | Pwith_modsubst (li, li2) ->
+ pp f "module %a :=@ %a" longident_loc li longident_loc li2
+ | Pwith_module_typesubst (li, li2) ->
+ pp f "module type %a :=@ %a" longident_loc li longident_loc li2
+
+
and module_type1 ctxt f x =
if x.pmty_attributes <> [] then module_type ctxt f x
else match x.pmty_desc with
diff --git a/parsing/printast.ml b/parsing/printast.ml
index 031cd7b57c..c196256ecd 100644
--- a/parsing/printast.ml
+++ b/parsing/printast.ml
@@ -771,6 +771,14 @@ and with_constraint i ppf x =
line i ppf "Pwith_modsubst %a = %a\n"
fmt_longident_loc lid1
fmt_longident_loc lid2;
+ | Pwith_module_type (lid1, lid2) ->
+ line i ppf "Pwith_module_type %a = %a\n"
+ fmt_longident_loc lid1
+ fmt_longident_loc lid2
+ | Pwith_module_typesubst (lid1, lid2) ->
+ line i ppf "Pwith_module_typesubst %a = %a\n"
+ fmt_longident_loc lid1
+ fmt_longident_loc lid2
and module_expr i ppf x =
line i ppf "module_expr %a\n" fmt_location x.pmod_loc;
diff --git a/typing/includemod.ml b/typing/includemod.ml
index 87a5b8ff2e..d5d6e3da5f 100644
--- a/typing/includemod.ml
+++ b/typing/includemod.ml
@@ -568,6 +568,9 @@ let check_modtype_inclusion ~loc env mty1 path1 mty2 =
(strengthened_modtypes ~loc ~aliasable env ~mark:Mark_both []
Subst.identity mty1 path1 mty2)
+let check_modtype_equiv ~loc env mty1 mty2 =
+ check_modtype_equiv ~loc env ~mark:Mark_both [] mty1 mty2
+
let () =
Env.check_functor_application :=
(fun ~errors ~loc env mty1 path1 mty2 path2 ->
diff --git a/typing/includemod.mli b/typing/includemod.mli
index 855b7863c1..621d8d1861 100644
--- a/typing/includemod.mli
+++ b/typing/includemod.mli
@@ -46,6 +46,9 @@ val check_modtype_inclusion :
functor application F(M) is well typed, where mty2 is the type of
the argument of F and path1/mty1 is the path/unstrenghened type of M. *)
+val check_modtype_equiv:
+ loc:Location.t -> Env.t -> module_type -> module_type -> unit
+
val signatures: Env.t -> mark:mark ->
signature -> signature -> module_coercion
diff --git a/typing/printtyped.ml b/typing/printtyped.ml
index c9ae218a3f..f11dc3bdeb 100644
--- a/typing/printtyped.ml
+++ b/typing/printtyped.ml
@@ -780,6 +780,10 @@ and with_constraint i ppf x =
type_declaration (i+1) ppf td;
| Twith_module (li,_) -> line i ppf "Twith_module %a\n" fmt_path li;
| Twith_modsubst (li,_) -> line i ppf "Twith_modsubst %a\n" fmt_path li;
+ | Twith_module_type (p,_) ->
+ line i ppf "Twith_module_type %a\n" fmt_path p
+ | Twith_module_typesubst (p,_) ->
+ line i ppf "Twith_module_typesubst %a\n" fmt_path p
and module_expr i ppf x =
line i ppf "module_expr %a\n" fmt_location x.mod_loc;
diff --git a/typing/tast_iterator.ml b/typing/tast_iterator.ml
index 640ad6b1e0..90ed15be1c 100644
--- a/typing/tast_iterator.ml
+++ b/typing/tast_iterator.ml
@@ -316,6 +316,9 @@ let with_constraint sub = function
| Twith_typesubst decl -> sub.type_declaration sub decl
| Twith_module _ -> ()
| Twith_modsubst _ -> ()
+ | Twith_module_type _ -> ()
+ | Twith_module_typesubst _ -> ()
+
let open_description sub {open_env; _} = sub.env sub open_env
diff --git a/typing/tast_mapper.ml b/typing/tast_mapper.ml
index 2c1d13ae77..555e09d7d3 100644
--- a/typing/tast_mapper.ml
+++ b/typing/tast_mapper.ml
@@ -458,7 +458,9 @@ let with_constraint sub = function
| Twith_type decl -> Twith_type (sub.type_declaration sub decl)
| Twith_typesubst decl -> Twith_typesubst (sub.type_declaration sub decl)
| Twith_module _
- | Twith_modsubst _ as d -> d
+ | Twith_modsubst _
+ | Twith_module_type _
+ | Twith_module_typesubst _ as d -> d
let open_description sub od =
{od with open_env = sub.env sub od.open_env}
diff --git a/typing/typedtree.ml b/typing/typedtree.ml
index 4364e91c3c..63ead794cb 100644
--- a/typing/typedtree.ml
+++ b/typing/typedtree.ml
@@ -419,8 +419,11 @@ and include_declaration = module_expr include_infos
and with_constraint =
Twith_type of type_declaration
| Twith_module of Path.t * Longident.t loc
+ | Twith_module_type of Path.t * Longident.t loc
| Twith_typesubst of type_declaration
| Twith_modsubst of Path.t * Longident.t loc
+ | Twith_module_typesubst of Path.t * Longident.t loc
+
and core_type =
(* mutable because of [Typeclass.declare_method] *)
diff --git a/typing/typedtree.mli b/typing/typedtree.mli
index 1f23a5f7b3..dcd69610e7 100644
--- a/typing/typedtree.mli
+++ b/typing/typedtree.mli
@@ -559,8 +559,10 @@ and include_declaration = module_expr include_infos
and with_constraint =
Twith_type of type_declaration
| Twith_module of Path.t * Longident.t loc
+ | Twith_module_type of Path.t * Longident.t loc
| Twith_typesubst of type_declaration
| Twith_modsubst of Path.t * Longident.t loc
+ | Twith_module_typesubst of Path.t * Longident.t loc
and core_type =
{ mutable ctyp_desc : core_type_desc;
diff --git a/typing/typemod.ml b/typing/typemod.ml
index f3e35eef52..dacf2c4462 100644
--- a/typing/typemod.ml
+++ b/typing/typemod.ml
@@ -448,16 +448,21 @@ let params_are_constrained =
loop
;;
+let transl_modtype_longident loc env lid =
+ let (path, _info) = Env.lookup_modtype ~loc lid env in
+ path
+
let merge_constraint initial_env remove_aliases loc sg constr =
let lid =
match constr with
- | Pwith_type (lid, _) | Pwith_module (lid, _)
- | Pwith_typesubst (lid, _) | Pwith_modsubst (lid, _) -> lid
+ | Pwith_type (lid, _) | Pwith_module (lid, _) | Pwith_module_type (lid,_)
+ | Pwith_typesubst (lid, _) | Pwith_modsubst (lid, _)
+ | Pwith_module_typesubst (lid, _) -> lid
in
let destructive_substitution =
match constr with
- | Pwith_type _ | Pwith_module _ -> false
- | Pwith_typesubst _ | Pwith_modsubst _ -> true
+ | Pwith_type _ | Pwith_module _ | Pwith_module_type _ -> false
+ | Pwith_typesubst _ | Pwith_modsubst _ | Pwith_module_typesubst _ -> true
in
let real_ids = ref [] in
let rec merge sig_env sg namelist row_id =
@@ -530,6 +535,33 @@ let merge_constraint initial_env remove_aliases loc sg constr =
(Pident id, lid, Twith_typesubst tdecl),
update_rec_next rs rem
end
+ | (Sig_modtype(id, mtd, priv) :: rem, [s],
+ (Pwith_module_type (_, lmty) | Pwith_module_typesubst (_,lmty))
+ )
+ when Ident.name id = s ->
+ let path = transl_modtype_longident lmty.loc initial_env lmty.txt in
+ let () = match mtd.mtd_type with
+ | None -> ()
+ | Some previous_mty ->
+ Includemod.check_modtype_equiv ~loc sig_env
+ previous_mty (Mty_ident path)
+ in
+ if not destructive_substitution then
+ let mtd': modtype_declaration =
+ {
+ mtd_uid = Uid.mk ~current_unit:(Env.get_unit_name ());
+ mtd_type = Some (Mty_ident path);
+ mtd_attributes = [];
+ mtd_loc = loc;
+ }
+ in
+ (Pident id, lid, Twith_module_type (path,lmty)),
+ Sig_modtype(id, mtd', priv) :: rem
+ else begin
+ real_ids := [Pident id];
+ (Pident id, lid, Twith_module_typesubst (path,lmty)),
+ rem
+ end
| (Sig_type(id, _, _, _) :: rem, [s], (Pwith_type _ | Pwith_typesubst _))
when Ident.name id = s ^ "#row" ->
merge sig_env rem namelist (Some id)
@@ -635,6 +667,12 @@ let merge_constraint initial_env remove_aliases loc sg constr =
in
(* See explanation in the [Twith_typesubst] case above. *)
Subst.signature Make_local sub sg
+ | (_, _, Twith_module_typesubst (p,_)) ->
+ let add s = function
+ | Pident id -> Subst.add_modtype id (Mty_ident p) s
+ | _ -> s in
+ let sub = List.fold_left add Subst.identity !real_ids in
+ Subst.signature Make_local sub sg
| _ ->
sg
in
@@ -722,8 +760,10 @@ let rec approx_modtype env smty =
List.iter
(fun sdecl ->
match sdecl with
- | Pwith_type _ -> ()
- | Pwith_typesubst _ -> ()
+ | Pwith_type _
+ | Pwith_typesubst _
+ | Pwith_module_type _
+ | Pwith_module_typesubst _ -> ()
| Pwith_module (_, lid') ->
(* Lookup the module to make sure that it is not recursive.
(GPR#1626) *)
@@ -1103,10 +1143,6 @@ let has_remove_aliases_attribute attr =
(* Check and translate a module type expression *)
-let transl_modtype_longident loc env lid =
- let (path, _info) = Env.lookup_modtype ~loc lid env in
- path
-
let transl_module_alias loc env lid =
Env.lookup_module_path ~load:false ~loc lid env
diff --git a/typing/untypeast.ml b/typing/untypeast.ml
index 657ce517df..bff1e29a06 100644
--- a/typing/untypeast.ml
+++ b/typing/untypeast.ml
@@ -636,10 +636,14 @@ let with_constraint sub (_path, lid, cstr) =
Pwith_type (map_loc sub lid, sub.type_declaration sub decl)
| Twith_module (_path, lid2) ->
Pwith_module (map_loc sub lid, map_loc sub lid2)
+ | Twith_module_type (_path,lid2) ->
+ Pwith_module_type (map_loc sub lid, map_loc sub lid2)
| Twith_typesubst decl ->
Pwith_typesubst (map_loc sub lid, sub.type_declaration sub decl)
| Twith_modsubst (_path, lid2) ->
Pwith_modsubst (map_loc sub lid, map_loc sub lid2)
+ | Twith_module_typesubst (_path, lid2) ->
+ Pwith_module_typesubst (map_loc sub lid, map_loc sub lid2)
let module_expr (sub : mapper) mexpr =
let loc = sub.location sub mexpr.mod_loc in