Skip to content

Commit d060f62

Browse files
lukemaurerEkdohibs
authored andcommitted
Add code path to read .cmi without adding to environment (ocaml-flambda#1674)
Currently, every time a .cmi is read for any reason, we bind the name of the module in the environment. In nearly every case, this is undesirable: for instance, if we're reading the .cmi for the current module, we do _not_ want to add the current module to its own environment. This behavior is largely benign at the moment since we read .cmi files after typechecking, but parameterised libraries will complicate this picture.
1 parent c59bb51 commit d060f62

File tree

6 files changed

+35
-17
lines changed

6 files changed

+35
-17
lines changed

ocaml/debugger/loadprinter.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ let init () =
9999
let topdirs =
100100
Filename.concat !Parameters.topdirs_path "topdirs.cmi" in
101101
let topdirs_unit = "Topdirs" |> Compilation_unit.of_string in
102-
ignore (Env.read_signature topdirs_unit topdirs)
102+
ignore (Env.read_signature topdirs_unit topdirs ~add_binding:true)
103103

104104
let match_printer_type desc typename =
105105
let printer_type =

ocaml/typing/env.ml

+6-3
Original file line numberDiff line numberDiff line change
@@ -974,8 +974,9 @@ let imports () = Persistent_env.imports !persistent_env
974974
let import_crcs ~source crcs =
975975
Persistent_env.import_crcs !persistent_env ~source crcs
976976

977-
let read_pers_mod modname filename =
977+
let read_pers_mod modname filename ~add_binding =
978978
Persistent_env.read !persistent_env read_sign_of_cmi modname filename
979+
~add_binding
979980

980981
let find_pers_mod name =
981982
Persistent_env.find !persistent_env read_sign_of_cmi name
@@ -2617,8 +2618,10 @@ let open_signature
26172618
else open_signature None root env
26182619

26192620
(* Read a signature from a file *)
2620-
let read_signature modname filename =
2621-
let mda = read_pers_mod (Compilation_unit.name modname) filename in
2621+
let read_signature modname filename ~add_binding =
2622+
let mda =
2623+
read_pers_mod (Compilation_unit.name modname) filename ~add_binding
2624+
in
26222625
let md = Subst.Lazy.force_module_decl mda.mda_declaration in
26232626
match md.md_type with
26242627
| Mty_signature sg -> sg

ocaml/typing/env.mli

+5-2
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,11 @@ val set_unit_name: Compilation_unit.t option -> unit
419419
val get_unit_name: unit -> Compilation_unit.t option
420420

421421
(* Read, save a signature to/from a file *)
422-
val read_signature: Compilation_unit.t -> filepath -> signature
423-
(* Arguments: module name, file name. Results: signature. *)
422+
val read_signature:
423+
Compilation_unit.t -> filepath -> add_binding:bool -> signature
424+
(* Arguments: module name, file name, [add_binding] flag.
425+
Results: signature. If [add_binding] is true, creates an entry for
426+
the module in the environment. *)
424427
val save_signature:
425428
alerts:alerts -> signature -> Compilation_unit.t -> filepath
426429
-> Cmi_format.cmi_infos_lazy

ocaml/typing/persistent_env.ml

+14-6
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ let save_pers_struct penv crc comp_unit flags filename =
181181
Consistbl.set crc_units modname comp_unit crc filename;
182182
add_import penv modname
183183

184-
let acknowledge_pers_struct penv check modname pers_sig pm =
184+
let process_pers_struct penv check modname pers_sig =
185185
let { Persistent_signature.filename; cmi } = pers_sig in
186186
let name = cmi.cmi_name in
187187
let crcs = cmi.cmi_crcs in
@@ -216,16 +216,24 @@ let acknowledge_pers_struct penv check modname pers_sig pm =
216216
error (Direct_reference_from_wrong_package (name, filename, prefix));
217217
| None -> ()
218218
end;
219+
ps
220+
221+
let bind_pers_struct penv modname ps pm =
219222
let {persistent_structures; _} = penv in
220-
Hashtbl.add persistent_structures modname (Found (ps, pm));
223+
Hashtbl.add persistent_structures modname (Found (ps, pm))
224+
225+
let acknowledge_pers_struct penv check modname pers_sig pm =
226+
let ps = process_pers_struct penv check modname pers_sig in
227+
bind_pers_struct penv modname ps pm;
221228
ps
222229

223-
let read_pers_struct penv val_of_pers_sig check modname filename =
230+
let read_pers_struct penv val_of_pers_sig check modname filename ~add_binding =
224231
add_import penv modname;
225232
let cmi = read_cmi_lazy filename in
226233
let pers_sig = { Persistent_signature.filename; cmi } in
227234
let pm = val_of_pers_sig pers_sig in
228-
let ps = acknowledge_pers_struct penv check modname pers_sig pm in
235+
let ps = process_pers_struct penv check modname pers_sig in
236+
if add_binding then bind_pers_struct penv modname ps pm;
229237
(ps, pm)
230238

231239
let find_pers_struct penv val_of_pers_sig check name =
@@ -297,8 +305,8 @@ let check_pers_struct penv f ~loc name =
297305
let warn = Warnings.No_cmi_file(name_as_string, Some msg) in
298306
Location.prerr_warning loc warn
299307

300-
let read penv f modname filename =
301-
snd (read_pers_struct penv f true modname filename)
308+
let read penv f modname filename ~add_binding =
309+
snd (read_pers_struct penv f true modname filename ~add_binding)
302310

303311
let find penv f name =
304312
snd (find_pers_struct penv f true name)

ocaml/typing/persistent_env.mli

+3-1
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@ val clear_missing : 'a t -> unit
5959

6060
val fold : 'a t -> (Compilation_unit.Name.t -> 'a -> 'b -> 'b) -> 'b -> 'b
6161

62+
(* If [add_binding] is false, reads the signature from the .cmi but does not
63+
bind the module name in the environment. *)
6264
val read : 'a t -> (Persistent_signature.t -> 'a)
63-
-> Compilation_unit.Name.t -> filepath -> 'a
65+
-> Compilation_unit.Name.t -> filepath -> add_binding:bool -> 'a
6466
val find : 'a t -> (Persistent_signature.t -> 'a)
6567
-> Compilation_unit.Name.t -> 'a
6668

ocaml/typing/typemod.ml

+6-4
Original file line numberDiff line numberDiff line change
@@ -3256,7 +3256,8 @@ let type_implementation sourcefile outputprefix modulename initial_env ast =
32563256
with Not_found ->
32573257
raise(Error(Location.in_file sourcefile, Env.empty,
32583258
Interface_not_compiled sourceintf)) in
3259-
let dclsig = Env.read_signature modulename intf_file in
3259+
let dclsig =
3260+
Env.read_signature modulename intf_file ~add_binding:false in
32603261
let coercion, shape =
32613262
Profile.record_call "check_sig" (fun () ->
32623263
Includemod.compunit initial_env ~mark:Mark_positive
@@ -3389,14 +3390,15 @@ let package_units initial_env objfiles cmifile modulename =
33893390
|> Compilation_unit.Name.of_string
33903391
in
33913392
let modname = Compilation_unit.create_child modulename unit in
3392-
let sg = Env.read_signature modname (pref ^ ".cmi") in
3393+
let sg =
3394+
Env.read_signature modname (pref ^ ".cmi") ~add_binding:false in
33933395
if Filename.check_suffix f ".cmi" &&
33943396
not(Mtype.no_code_needed_sig (Lazy.force Env.initial_safe_string)
33953397
sg)
33963398
then raise(Error(Location.none, Env.empty,
33973399
Implementation_is_required f));
33983400
Compilation_unit.name modname,
3399-
Env.read_signature modname (pref ^ ".cmi"))
3401+
Env.read_signature modname (pref ^ ".cmi") ~add_binding:false)
34003402
objfiles in
34013403
(* Compute signature of packaged unit *)
34023404
Ident.reinit();
@@ -3419,7 +3421,7 @@ let package_units initial_env objfiles cmifile modulename =
34193421
raise(Error(Location.in_file mlifile, Env.empty,
34203422
Interface_not_compiled mlifile))
34213423
end;
3422-
let dclsig = Env.read_signature modulename cmifile in
3424+
let dclsig = Env.read_signature modulename cmifile ~add_binding:false in
34233425
let cc, _shape =
34243426
Includemod.compunit initial_env ~mark:Mark_both
34253427
"(obtained by packing)" sg mlifile dclsig shape

0 commit comments

Comments
 (0)