Implement type-checking of open by copying 'components' instead of recreating them from the signature.

master
alainfrisch 2016-09-28 00:07:53 +02:00
parent 55808123c3
commit 3d037367a2
4 changed files with 75 additions and 51 deletions

View File

@ -1777,43 +1777,81 @@ let rec add_signature sg env =
(* Open a signature path *) (* Open a signature path *)
let open_signature slot root sg env0 = let open_signature slot root env0 =
(* First build the paths and substitution *) let comps =
let (pl, _sub, sg) = prefix_idents_and_subst root Subst.identity sg in match get_components (find_module_descr root env0) with
let sg = Lazy.force sg in | Structure_comps c -> c
| Functor_comps _ -> assert false
in
(* Then enter the components in the environment after substitution *) let add_l w comps env0 =
Tbl.fold
let newenv = (fun name ->
List.fold_left2 List.fold_right
(fun env item p -> (fun (c, _) acc ->
match item with EnvTbl.add slot w (Ident.hide (Ident.create name)) c acc env0
Sig_value(id, decl) -> )
store_value slot (Ident.hide id) p decl env env0
| Sig_type(id, decl, _) ->
store_type ~check:false slot (Ident.hide id) p decl env env0
| Sig_typext(id, ext, _) ->
store_extension ~check:false slot (Ident.hide id) p ext env env0
| Sig_module(id, mty, _) ->
store_module ~check:false slot (Ident.hide id) p mty env env0
| Sig_modtype(id, decl) ->
store_modtype slot (Ident.hide id) p decl env env0
| Sig_class(id, decl, _) ->
store_class slot (Ident.hide id) p decl env env0
| Sig_class_type(id, decl, _) ->
store_cltype slot (Ident.hide id) p decl env env0
) )
env0 sg pl in comps env0
{ newenv with summary = Env_open(env0.summary, root) } in
let add_map w comps env0 f =
Tbl.fold
(fun name (c, pos) acc ->
EnvTbl.add slot w (Ident.hide (Ident.create name))
(Pdot (root, name, pos), f c) acc env0
)
comps env0
in
let add w comps env0 = add_map w comps env0 (fun x -> x) in
let constrs =
add_l (fun x -> `Constructor x) comps.comp_constrs env0.constrs
in
let labels =
add_l (fun x -> `Label x) comps.comp_labels env0.labels
in
let values =
add (fun x -> `Value x) comps.comp_values env0.values
in
let types =
add (fun x -> `Type x) comps.comp_types env0.types
in
let modtypes =
add (fun x -> `Module_type x) comps.comp_modtypes env0.modtypes
in
let classes =
add (fun x -> `Class x) comps.comp_classes env0.classes
in
let cltypes =
add (fun x -> `Class_type x) comps.comp_cltypes env0.cltypes
in
let components =
add (fun x -> `Component x) comps.comp_components env0.components
in
let modules =
(* one should avoid this force, by allowing lazy in env as well *)
add_map (fun x -> `Module x) comps.comp_modules env0.modules
(fun data -> md (EnvLazy.force subst_modtype_maker data))
in
{ env0 with
summary = Env_open(env0.summary, root);
constrs;
labels;
values;
types;
modtypes;
classes;
cltypes;
components;
modules;
}
(* Open a signature from a file *) (* Open a signature from a file *)
let open_pers_signature name env = let open_pers_signature name env =
let ps = find_pers_struct name in open_signature None (Pident(Ident.create_persistent name)) env
open_signature None (Pident(Ident.create_persistent name))
(Lazy.force ps.ps_sig) env
let open_signature ?(loc = Location.none) ?(toplevel = false) ovf root sg env = let open_signature ?(loc = Location.none) ?(toplevel = false) ovf root env =
if not toplevel && ovf = Asttypes.Fresh && not loc.Location.loc_ghost if not toplevel && ovf = Asttypes.Fresh && not loc.Location.loc_ghost
&& (Warnings.is_active (Warnings.Unused_open "") && (Warnings.is_active (Warnings.Unused_open "")
|| Warnings.is_active (Warnings.Open_shadow_identifier ("", "")) || Warnings.is_active (Warnings.Open_shadow_identifier ("", ""))
@ -1841,9 +1879,9 @@ let open_signature ?(loc = Location.none) ?(toplevel = false) ovf root sg env =
end; end;
used := true used := true
in in
open_signature (Some slot) root sg env open_signature (Some slot) root env
end end
else open_signature None root sg env else open_signature None root env
(* Read a signature from a file *) (* Read a signature from a file *)

View File

@ -157,7 +157,7 @@ val add_signature: signature -> t -> t
val open_signature: val open_signature:
?loc:Location.t -> ?toplevel:bool -> Asttypes.override_flag -> Path.t -> ?loc:Location.t -> ?toplevel:bool -> Asttypes.override_flag -> Path.t ->
signature -> t -> t t -> t
val open_pers_signature: string -> t -> t val open_pers_signature: string -> t -> t
(* Insertion by name *) (* Insertion by name *)

View File

@ -14,8 +14,6 @@
(* *) (* *)
(**************************************************************************) (**************************************************************************)
open Misc
open Types
open Env open Env
type error = type error =
@ -30,11 +28,6 @@ let reset_cache () =
Hashtbl.clear env_cache; Hashtbl.clear env_cache;
Env.reset_cache() Env.reset_cache()
let extract_sig env mty =
match Env.scrape_alias env mty with
Mty_signature sg -> sg
| _ -> fatal_error "Envaux.extract_sig"
let rec env_from_summary sum subst = let rec env_from_summary sum subst =
try try
Hashtbl.find env_cache (sum, subst) Hashtbl.find env_cache (sum, subst)
@ -70,14 +63,7 @@ let rec env_from_summary sum subst =
| Env_open(s, path) -> | Env_open(s, path) ->
let env = env_from_summary s subst in let env = env_from_summary s subst in
let path' = Subst.module_path subst path in let path' = Subst.module_path subst path in
let md = Env.open_signature Asttypes.Override path' env
try
Env.find_module path' env
with Not_found ->
raise (Error (Module_not_found path'))
in
Env.open_signature Asttypes.Override path'
(extract_sig env md.md_type) env
| Env_functor_arg(Env_module(s, id, desc), id') when Ident.same id id' -> | Env_functor_arg(Env_module(s, id, desc), id') when Ident.same id id' ->
Env.add_module_declaration ~check:false Env.add_module_declaration ~check:false
id (Subst.module_declaration subst desc) id (Subst.module_declaration subst desc)

View File

@ -83,9 +83,9 @@ let extract_sig_open env loc mty =
(* Compute the environment after opening a module *) (* Compute the environment after opening a module *)
let type_open_ ?toplevel ovf env loc lid = let type_open_ ?toplevel ovf env loc lid =
let path, md = Typetexp.find_module env lid.loc lid.txt in let path = Typetexp.lookup_module ~load:true env lid.loc lid.txt in
let sg = extract_sig_open env lid.loc md.md_type in (* TODO: handle same errors as in extract_sig_open *)
path, Env.open_signature ~loc ?toplevel ovf path sg env path, Env.open_signature ~loc ?toplevel ovf path env
let type_open ?toplevel env sod = let type_open ?toplevel env sod =
let (path, newenv) = let (path, newenv) =