aboutsummaryrefslogtreecommitdiffhomepage
path: root/kernel/safe_typing.ml
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/safe_typing.ml')
-rw-r--r--kernel/safe_typing.ml152
1 files changed, 118 insertions, 34 deletions
diff --git a/kernel/safe_typing.ml b/kernel/safe_typing.ml
index 28e6fb8c7..b1eea3bbd 100644
--- a/kernel/safe_typing.ml
+++ b/kernel/safe_typing.ml
@@ -25,11 +25,12 @@ open Term_typing
open Modops
open Subtyping
open Mod_typing
+open Mod_subst
type modvariant =
| NONE
- | SIG of (* funsig params *) (mod_bound_id * struct_expr_body) list
- | STRUCT of (* functor params *) (mod_bound_id * struct_expr_body) list
+ | SIG of (* funsig params *) (mod_bound_id * module_type_body) list
+ | STRUCT of (* functor params *) (mod_bound_id * module_type_body) list
| LIBRARY of dir_path
type module_info =
@@ -37,7 +38,8 @@ type module_info =
modpath : module_path;
seed : dir_path; (* the "seed" of unique identifier generator *)
label : label;
- variant : modvariant}
+ variant : modvariant;
+ alias_subst : substitution}
let check_label l labset =
if Labset.mem l labset then error_existing_label l
@@ -81,7 +83,8 @@ let rec empty_environment =
modpath = initial_path;
seed = initial_dir;
label = mk_label "_";
- variant = NONE};
+ variant = NONE;
+ alias_subst = empty_subst};
labset = Labset.empty;
revstruct = [];
univ = Univ.Constraint.empty;
@@ -253,10 +256,13 @@ let add_mind dir l mie senv =
let add_modtype l mte senv =
check_label l senv.labset;
- let mtb = translate_struct_entry senv.env mte in
+ let mtb_expr,sub = translate_struct_entry senv.env mte in
+ let mtb = { typ_expr = mtb_expr;
+ typ_strength = None;
+ typ_alias = sub} in
let env' = add_modtype_constraints senv.env mtb in
let mp = MPdot(senv.modinfo.modpath, l) in
- let env'' = Environ.add_modtype mp (mtb,None) env' in
+ let env'' = Environ.add_modtype mp mtb env' in
mp, { old = senv.old;
env = env'';
modinfo = senv.modinfo;
@@ -281,10 +287,16 @@ let add_module l me senv =
check_label l senv.labset;
let mb = translate_module senv.env me in
let mp = MPdot(senv.modinfo.modpath, l) in
+ let is_functor,sub = Modops.update_subst senv.env mb mp in
let env' = full_add_module mp mb senv.env in
mp, { old = senv.old;
env = env';
- modinfo = senv.modinfo;
+ modinfo =
+ if is_functor then
+ senv.modinfo
+ else
+ {senv.modinfo with
+ alias_subst = join senv.modinfo.alias_subst sub};
labset = Labset.add l senv.labset;
revstruct = (l,SFBmodule mb)::senv.revstruct;
univ = senv.univ;
@@ -293,6 +305,26 @@ let add_module l me senv =
loads = senv.loads;
local_retroknowledge = senv.local_retroknowledge }
+let add_alias l mp senv =
+ check_label l senv.labset;
+ let mp' = MPdot(senv.modinfo.modpath, l) in
+ (* we get all alias substitutions that comes from mp *)
+ let _,sub = translate_struct_entry senv.env (MSEident mp) in
+ (* we add the new one *)
+ let sub = join (map_mp mp' mp) sub in
+ let env' = register_alias mp' mp senv.env in
+ mp', { old = senv.old;
+ env = env';
+ modinfo = { senv.modinfo with
+ alias_subst = join
+ senv.modinfo.alias_subst sub};
+ labset = Labset.add l senv.labset;
+ revstruct = (l,SFBalias (mp,None))::senv.revstruct;
+ univ = senv.univ;
+ engagement = senv.engagement;
+ imports = senv.imports;
+ loads = senv.loads;
+ local_retroknowledge = senv.local_retroknowledge }
(* Interactive modules *)
@@ -304,7 +336,8 @@ let start_module l senv =
modpath = mp;
seed = senv.modinfo.seed;
label = l;
- variant = STRUCT [] }
+ variant = STRUCT [];
+ alias_subst = empty_subst}
in
mp, { old = senv;
env = senv.env;
@@ -322,10 +355,10 @@ let end_module l restype senv =
let oldsenv = senv.old in
let modinfo = senv.modinfo in
let restype = Option.map (translate_struct_entry senv.env) restype in
- let params =
+ let params,is_functor =
match modinfo.variant with
| NONE | LIBRARY _ | SIG _ -> error_no_module_to_end ()
- | STRUCT params -> params
+ | STRUCT params -> params, (List.length params > 0)
in
if l <> modinfo.label then error_incompatible_labels l modinfo.label;
if not (empty_context senv.env) then error_local_context None;
@@ -339,21 +372,27 @@ let end_module l restype senv =
let auto_tb =
SEBstruct (modinfo.msid, List.rev senv.revstruct)
in
- let mod_typ, cst =
+ let mod_typ,subst,cst =
match restype with
- | None -> None, Constraint.empty
- | Some res_tb ->
- let cst = check_subtypes senv.env auto_tb res_tb in
+ | None -> None,modinfo.alias_subst,Constraint.empty
+ | Some (res_tb,subst) ->
+ let cst = check_subtypes senv.env
+ {typ_expr = auto_tb;
+ typ_strength = None;
+ typ_alias = modinfo.alias_subst}
+ {typ_expr = res_tb;
+ typ_strength = None;
+ typ_alias = subst} in
let mtb = functorize_struct res_tb in
- Some mtb, cst
+ Some mtb,subst,cst
in
let mexpr = functorize_struct auto_tb in
let cst = Constraint.union cst senv.univ in
let mb =
{ mod_expr = Some mexpr;
mod_type = mod_typ;
- mod_equiv = None;
mod_constraints = cst;
+ mod_alias = subst;
mod_retroknowledge = senv.local_retroknowledge }
in
let mp = MPdot (oldsenv.modinfo.modpath, l) in
@@ -368,9 +407,19 @@ let end_module l restype senv =
let newenv =
full_add_module mp mb newenv
in
- mp, { old = oldsenv.old;
+ let is_functor,subst = Modops.update_subst newenv mb mp in
+ let newmodinfo =
+ if is_functor then
+ oldsenv.modinfo
+ else
+ { oldsenv.modinfo with
+ alias_subst = join
+ oldsenv.modinfo.alias_subst
+ subst };
+ in
+ mp, { old = oldsenv.old;
env = newenv;
- modinfo = oldsenv.modinfo;
+ modinfo = newmodinfo;
labset = Labset.add l oldsenv.labset;
revstruct = (l,SFBmodule mb)::oldsenv.revstruct;
univ = oldsenv.univ;
@@ -383,8 +432,8 @@ let end_module l restype senv =
(* Include for module and module type*)
let add_include me senv =
- let struct_expr = translate_struct_entry senv.env me in
- let senv = { senv with env = add_modtype_constraints senv.env struct_expr } in
+ let struct_expr,_ = translate_struct_entry senv.env me in
+ let senv = { senv with env = add_struct_expr_constraints senv.env struct_expr } in
let msid,str = match (eval_struct senv.env struct_expr) with
| SEBstruct(msid,str_l) -> msid,str_l
| _ -> error ("You cannot Include a higher-order Module or Module Type" )
@@ -426,21 +475,42 @@ let end_module l restype senv =
| SFBmodule mb ->
let mp = MPdot(senv.modinfo.modpath, l) in
+ let is_functor,sub = Modops.update_subst senv.env mb mp in
let env' = full_add_module mp mb senv.env in
{ old = senv.old;
env = env';
- modinfo = senv.modinfo;
+ modinfo =
+ if is_functor then
+ senv.modinfo
+ else
+ {senv.modinfo with
+ alias_subst = join senv.modinfo.alias_subst sub};
labset = Labset.add l senv.labset;
revstruct = (l,SFBmodule mb)::senv.revstruct;
+ univ = senv.univ;
+ engagement = senv.engagement;
+ imports = senv.imports;
+ loads = senv.loads;
+ local_retroknowledge = senv.local_retroknowledge }
+ | SFBalias (mp',cst) ->
+ let env' = Option.fold_right
+ Environ.add_constraints cst senv.env in
+ let mp = MPdot(senv.modinfo.modpath, l) in
+ let env' = register_alias mp mp' env' in
+ { old = senv.old;
+ env = env';
+ modinfo = senv.modinfo;
+ labset = Labset.add l senv.labset;
+ revstruct = (l,SFBalias (mp,cst))::senv.revstruct;
univ = senv.univ;
engagement = senv.engagement;
imports = senv.imports;
loads = senv.loads;
- local_retroknowledge = senv.local_retroknowledge }
+ local_retroknowledge = senv.local_retroknowledge }
| SFBmodtype mtb ->
let env' = add_modtype_constraints senv.env mtb in
let mp = MPdot(senv.modinfo.modpath, l) in
- let env'' = Environ.add_modtype mp (mtb,None) env' in
+ let env'' = Environ.add_modtype mp mtb env' in
{ old = senv.old;
env = env'';
modinfo = senv.modinfo;
@@ -459,7 +529,10 @@ let end_module l restype senv =
let add_module_parameter mbid mte senv =
if senv.revstruct <> [] or senv.loads <> [] then
anomaly "Cannot add a module parameter to a non empty module";
- let mtb = translate_struct_entry senv.env mte in
+ let mtb_expr,sub = translate_struct_entry senv.env mte in
+ let mtb = {typ_expr = mtb_expr;
+ typ_strength = None;
+ typ_alias = sub} in
let env = full_add_module (MPbound mbid) (module_body_of_type mtb) senv.env
in
let new_variant = match senv.modinfo.variant with
@@ -490,7 +563,8 @@ let start_modtype l senv =
modpath = mp;
seed = senv.modinfo.seed;
label = l;
- variant = SIG [] }
+ variant = SIG [];
+ alias_subst = empty_subst }
in
mp, { old = senv;
env = senv.env;
@@ -517,7 +591,7 @@ let end_modtype l senv =
let auto_tb =
SEBstruct (modinfo.msid, List.rev senv.revstruct)
in
- let mtb =
+ let mtb_expr =
List.fold_left
(fun mtb (arg_id,arg_b) ->
SEBfunctor(arg_id,arg_b,mtb))
@@ -536,11 +610,15 @@ let end_modtype l senv =
newenv
(List.rev senv.loads)
in
+ let subst = senv.modinfo.alias_subst in
+ let mtb = {typ_expr = mtb_expr;
+ typ_strength = None;
+ typ_alias = subst} in
let newenv =
- add_modtype_constraints newenv mtb
+ add_modtype_constraints newenv mtb
in
let newenv =
- Environ.add_modtype mp (mtb,None) newenv
+ Environ.add_modtype mp mtb newenv
in
mp, { old = oldsenv.old;
env = newenv;
@@ -607,7 +685,8 @@ let start_library dir senv =
modpath = mp;
seed = dir;
label = l;
- variant = LIBRARY dir }
+ variant = LIBRARY dir;
+ alias_subst = empty_subst }
in
mp, { old = senv;
env = senv.env;
@@ -637,8 +716,8 @@ let export senv dir =
let mb =
{ mod_expr = Some (SEBstruct (modinfo.msid, List.rev senv.revstruct));
mod_type = None;
- mod_equiv = None;
mod_constraints = senv.univ;
+ mod_alias = senv.modinfo.alias_subst;
mod_retroknowledge = senv.local_retroknowledge}
in
modinfo.msid, (dir,mb,senv.imports,engagement senv.env)
@@ -692,15 +771,20 @@ let import (dp,mb,depends,engmt) digest senv =
and lighten_struct struc =
let lighten_body (l,body) = (l,match body with
| SFBconst ({const_opaque=true} as x) -> SFBconst {x with const_body=None}
- | (SFBconst _ | SFBmind _) as x -> x
+ | (SFBconst _ | SFBmind _ | SFBalias _) as x -> x
| SFBmodule m -> SFBmodule (lighten_module m)
- | SFBmodtype m -> SFBmodtype (lighten_modexpr m))
+ | SFBmodtype m -> SFBmodtype
+ ({m with
+ typ_expr = lighten_modexpr m.typ_expr}))
in
List.map lighten_body struc
and lighten_modexpr = function
| SEBfunctor (mbid,mty,mexpr) ->
- SEBfunctor (mbid,lighten_modexpr mty,lighten_modexpr mexpr)
+ SEBfunctor (mbid,
+ ({mty with
+ typ_expr = lighten_modexpr mty.typ_expr}),
+ lighten_modexpr mexpr)
| SEBident mp as x -> x
| SEBstruct (msid, struc) ->
SEBstruct (msid, lighten_struct struc)
@@ -708,7 +792,7 @@ and lighten_modexpr = function
SEBapply (lighten_modexpr mexpr,lighten_modexpr marg,u)
| SEBwith (seb,wdcl) ->
SEBwith (lighten_modexpr seb,wdcl)
-
+
let lighten_library (dp,mb,depends,s) = (dp,lighten_module mb,depends,s)