1 (***********************************************************************)
5 (* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
7 (* Copyright 1996 Institut National de Recherche en Informatique et *)
8 (* en Automatique. All rights reserved. This file is distributed *)
9 (* under the terms of the Q Public License version 1.0. *)
11 (***********************************************************************)
13 (* $Id: env.ml 9240 2009-04-28 05:11:54Z garrigue $ *)
15 (* Environment handling *)
26 Not_an_interface of string
27 | Corrupted_interface of string
28 | Illegal_renaming of string * string
29 | Inconsistent_import of string * string * string
30 | Need_recursive_types of string * string
32 exception Error of error
36 | Env_value of summary * Ident.t * value_description
37 | Env_type of summary * Ident.t * type_declaration
38 | Env_exception of summary * Ident.t * exception_declaration
39 | Env_module of summary * Ident.t * module_type
40 | Env_modtype of summary * Ident.t * modtype_declaration
41 | Env_class of summary * Ident.t * class_declaration
42 | Env_cltype of summary * Ident.t * cltype_declaration
43 | Env_open of summary * Path.t
46 values: (Path.t * value_description) Ident.tbl;
47 annotations: (Path.t * Annot.ident) Ident.tbl;
48 constrs: constructor_description Ident.tbl;
49 labels: label_description Ident.tbl;
50 types: (Path.t * type_declaration) Ident.tbl;
51 modules: (Path.t * module_type) Ident.tbl;
52 modtypes: (Path.t * modtype_declaration) Ident.tbl;
53 components: (Path.t * module_components) Ident.tbl;
54 classes: (Path.t * class_declaration) Ident.tbl;
55 cltypes: (Path.t * cltype_declaration) Ident.tbl;
59 and module_components = module_components_repr Lazy.t
61 and module_components_repr =
62 Structure_comps of structure_components
63 | Functor_comps of functor_components
65 and structure_components = {
66 mutable comp_values: (string, (value_description * int)) Tbl.t;
67 mutable comp_annotations: (string, (Annot.ident * int)) Tbl.t;
68 mutable comp_constrs: (string, (constructor_description * int)) Tbl.t;
69 mutable comp_labels: (string, (label_description * int)) Tbl.t;
70 mutable comp_types: (string, (type_declaration * int)) Tbl.t;
71 mutable comp_modules: (string, (module_type Lazy.t * int)) Tbl.t;
72 mutable comp_modtypes: (string, (modtype_declaration * int)) Tbl.t;
73 mutable comp_components: (string, (module_components * int)) Tbl.t;
74 mutable comp_classes: (string, (class_declaration * int)) Tbl.t;
75 mutable comp_cltypes: (string, (cltype_declaration * int)) Tbl.t
78 and functor_components = {
79 fcomp_param: Ident.t; (* Formal parameter *)
80 fcomp_arg: module_type; (* Argument signature *)
81 fcomp_res: module_type; (* Result signature *)
82 fcomp_env: t; (* Environment in which the result signature makes sense *)
83 fcomp_subst: Subst.t; (* Prefixing substitution for the result signature *)
84 fcomp_cache: (Path.t, module_components) Hashtbl.t (* For memoization *)
88 values = Ident.empty; annotations = Ident.empty; constrs = Ident.empty;
89 labels = Ident.empty; types = Ident.empty;
90 modules = Ident.empty; modtypes = Ident.empty;
91 components = Ident.empty; classes = Ident.empty;
92 cltypes = Ident.empty;
95 let diff_keys is_local tbl1 tbl2 =
96 let keys2 = Ident.keys tbl2 in
99 is_local (Ident.find_same id tbl2) &&
100 try ignore (Ident.find_same id tbl1); false with Not_found -> true)
103 let is_ident = function
105 | Pdot _ | Papply _ -> false
107 let is_local (p, _) = is_ident p
109 let is_local_exn = function
110 {cstr_tag = Cstr_exception p} -> is_ident p
114 diff_keys is_local env1.values env2.values @
115 diff_keys is_local_exn env1.constrs env2.constrs @
116 diff_keys is_local env1.modules env2.modules @
117 diff_keys is_local env1.classes env2.classes
119 (* Forward declarations *)
121 let components_of_module' =
122 ref ((fun env sub path mty -> assert false) :
123 t -> Subst.t -> Path.t -> module_type -> module_components)
124 let components_of_functor_appl' =
125 ref ((fun f p1 p2 -> assert false) :
126 functor_components -> Path.t -> Path.t -> module_components)
127 let check_modtype_inclusion =
128 (* to be filled with Includemod.check_modtype_inclusion *)
129 ref ((fun env mty1 path1 mty2 -> assert false) :
130 t -> module_type -> Path.t -> module_type -> unit)
132 (* The name of the compilation unit currently compiled.
133 "" if outside a compilation unit. *)
135 let current_unit = ref ""
137 (* Persistent structure descriptions *)
139 type pers_flags = Rectypes
144 ps_comps: module_components;
145 ps_crcs: (string * Digest.t) list;
147 ps_flags: pers_flags list }
149 let persistent_structures =
150 (Hashtbl.create 17 : (string, pers_struct) Hashtbl.t)
152 (* Consistency between persistent structures *)
154 let crc_units = Consistbl.create()
156 let check_consistency filename crcs =
159 (fun (name, crc) -> Consistbl.check crc_units name crc filename)
161 with Consistbl.Inconsistency(name, source, auth) ->
162 raise(Error(Inconsistent_import(name, auth, source)))
164 (* Reading persistent structures from .cmi files *)
166 let read_pers_struct modname filename =
167 let ic = open_in_bin filename in
169 let buffer = String.create (String.length cmi_magic_number) in
170 really_input ic buffer 0 (String.length cmi_magic_number);
171 if buffer <> cmi_magic_number then begin
173 raise(Error(Not_an_interface filename))
175 let (name, sign) = input_value ic in
176 let crcs = input_value ic in
177 let flags = input_value ic in
180 !components_of_module' empty Subst.identity
181 (Pident(Ident.create_persistent name))
182 (Tmty_signature sign) in
183 let ps = { ps_name = name;
187 ps_filename = filename;
188 ps_flags = flags } in
189 if ps.ps_name <> modname then
190 raise(Error(Illegal_renaming(ps.ps_name, filename)));
191 check_consistency filename ps.ps_crcs;
193 (function Rectypes ->
194 if not !Clflags.recursive_types then
195 raise(Error(Need_recursive_types(ps.ps_name, !current_unit))))
197 Hashtbl.add persistent_structures modname ps;
199 with End_of_file | Failure _ ->
201 raise(Error(Corrupted_interface(filename)))
203 let find_pers_struct name =
205 Hashtbl.find persistent_structures name
207 read_pers_struct name (find_in_path_uncap !load_path (name ^ ".cmi"))
211 Hashtbl.clear persistent_structures;
212 Consistbl.clear crc_units
214 let set_unit_name name =
217 (* Lookup by identifier *)
219 let rec find_module_descr path env =
223 let (p, desc) = Ident.find_same id env.components
226 if Ident.persistent id
227 then (find_pers_struct (Ident.name id)).ps_comps
231 begin match Lazy.force(find_module_descr p env) with
233 let (descr, pos) = Tbl.find s c.comp_components in
239 begin match Lazy.force(find_module_descr p1 env) with
241 !components_of_functor_appl' f p1 p2
242 | Structure_comps c ->
246 let find proj1 proj2 path env =
249 let (p, data) = Ident.find_same id (proj1 env)
252 begin match Lazy.force(find_module_descr p env) with
254 let (data, pos) = Tbl.find s (proj2 c) in data
262 find (fun env -> env.values) (fun sc -> sc.comp_values)
264 find (fun env -> env.types) (fun sc -> sc.comp_types)
266 find (fun env -> env.modtypes) (fun sc -> sc.comp_modtypes)
268 find (fun env -> env.classes) (fun sc -> sc.comp_classes)
270 find (fun env -> env.cltypes) (fun sc -> sc.comp_cltypes)
272 (* Find the manifest type associated to a type when appropriate:
273 - the type should be public or should have a private row,
274 - the type should have an associated manifest type. *)
275 let find_type_expansion path env =
276 let decl = find_type path env in
277 match decl.type_manifest with
278 | Some body when decl.type_private = Public
279 || decl.type_kind <> Type_abstract
280 || Btype.has_constr_row body -> (decl.type_params, body)
281 (* The manifest type of Private abstract data types without
282 private row are still considered unknown to the type system.
283 Hence, this case is caught by the following clause that also handles
284 purely abstract data types without manifest type definition. *)
285 | _ -> raise Not_found
287 (* Find the manifest type information associated to a type, i.e.
288 the necessary information for the compiler's type-based optimisations.
289 In particular, the manifest type associated to a private abstract type
290 is revealed for the sake of compiler's type-based optimisations. *)
291 let find_type_expansion_opt path env =
292 let decl = find_type path env in
293 match decl.type_manifest with
294 (* The manifest type of Private abstract data types can still get
295 an approximation using their manifest type. *)
296 | Some body -> (decl.type_params, body)
297 | _ -> raise Not_found
299 let find_modtype_expansion path env =
300 match find_modtype path env with
301 Tmodtype_abstract -> raise Not_found
302 | Tmodtype_manifest mty -> mty
304 let find_module path env =
308 let (p, data) = Ident.find_same id env.modules
311 if Ident.persistent id then
312 let ps = find_pers_struct (Ident.name id) in
313 Tmty_signature(ps.ps_sig)
317 begin match Lazy.force (find_module_descr p env) with
319 let (data, pos) = Tbl.find s c.comp_modules in Lazy.force data
324 raise Not_found (* not right *)
328 let rec lookup_module_descr lid env =
332 Ident.find_name s env.components
334 if s = !current_unit then raise Not_found;
335 let ps = find_pers_struct s in
336 (Pident(Ident.create_persistent s), ps.ps_comps)
339 let (p, descr) = lookup_module_descr l env in
340 begin match Lazy.force descr with
342 let (descr, pos) = Tbl.find s c.comp_components in
343 (Pdot(p, s, pos), descr)
348 let (p1, desc1) = lookup_module_descr l1 env in
349 let (p2, mty2) = lookup_module l2 env in
350 begin match Lazy.force desc1 with
352 !check_modtype_inclusion env mty2 p2 f.fcomp_arg;
353 (Papply(p1, p2), !components_of_functor_appl' f p1 p2)
354 | Structure_comps c ->
358 and lookup_module lid env =
362 Ident.find_name s env.modules
364 if s = !current_unit then raise Not_found;
365 let ps = find_pers_struct s in
366 (Pident(Ident.create_persistent s), Tmty_signature ps.ps_sig)
369 let (p, descr) = lookup_module_descr l env in
370 begin match Lazy.force descr with
372 let (data, pos) = Tbl.find s c.comp_modules in
373 (Pdot(p, s, pos), Lazy.force data)
378 let (p1, desc1) = lookup_module_descr l1 env in
379 let (p2, mty2) = lookup_module l2 env in
380 let p = Papply(p1, p2) in
381 begin match Lazy.force desc1 with
383 !check_modtype_inclusion env mty2 p2 f.fcomp_arg;
384 (p, Subst.modtype (Subst.add_module f.fcomp_param p2 f.fcomp_subst)
386 | Structure_comps c ->
390 let lookup proj1 proj2 lid env =
393 Ident.find_name s (proj1 env)
395 let (p, desc) = lookup_module_descr l env in
396 begin match Lazy.force desc with
398 let (data, pos) = Tbl.find s (proj2 c) in
399 (Pdot(p, s, pos), data)
406 let lookup_simple proj1 proj2 lid env =
409 Ident.find_name s (proj1 env)
411 let (p, desc) = lookup_module_descr l env in
412 begin match Lazy.force desc with
414 let (data, pos) = Tbl.find s (proj2 c) in
423 lookup (fun env -> env.values) (fun sc -> sc.comp_values)
424 let lookup_annot id e =
425 lookup (fun env -> env.annotations) (fun sc -> sc.comp_annotations) id e
426 and lookup_constructor =
427 lookup_simple (fun env -> env.constrs) (fun sc -> sc.comp_constrs)
429 lookup_simple (fun env -> env.labels) (fun sc -> sc.comp_labels)
431 lookup (fun env -> env.types) (fun sc -> sc.comp_types)
433 lookup (fun env -> env.modtypes) (fun sc -> sc.comp_modtypes)
435 lookup (fun env -> env.classes) (fun sc -> sc.comp_classes)
437 lookup (fun env -> env.cltypes) (fun sc -> sc.comp_cltypes)
439 (* Expand manifest module type names at the top of the given module type *)
441 let rec scrape_modtype mty env =
445 scrape_modtype (find_modtype_expansion path env) env
451 (* Compute constructor descriptions *)
453 let constructors_of_type ty_path decl =
454 match decl.type_kind with
455 Type_variant cstrs ->
456 Datarepr.constructor_descrs
457 (Btype.newgenty (Tconstr(ty_path, decl.type_params, ref Mnil)))
458 cstrs decl.type_private
459 | Type_record _ | Type_abstract -> []
461 (* Compute label descriptions *)
463 let labels_of_type ty_path decl =
464 match decl.type_kind with
465 Type_record(labels, rep) ->
466 Datarepr.label_descrs
467 (Btype.newgenty (Tconstr(ty_path, decl.type_params, ref Mnil)))
468 labels rep decl.type_private
469 | Type_variant _ | Type_abstract -> []
471 (* Given a signature and a root path, prefix all idents in the signature
472 by the root path and build the corresponding substitution. *)
474 let rec prefix_idents root pos sub = function
476 | Tsig_value(id, decl) :: rem ->
477 let p = Pdot(root, Ident.name id, pos) in
478 let nextpos = match decl.val_kind with Val_prim _ -> pos | _ -> pos+1 in
479 let (pl, final_sub) = prefix_idents root nextpos sub rem in
481 | Tsig_type(id, decl, _) :: rem ->
482 let p = Pdot(root, Ident.name id, nopos) in
483 let (pl, final_sub) =
484 prefix_idents root pos (Subst.add_type id p sub) rem in
486 | Tsig_exception(id, decl) :: rem ->
487 let p = Pdot(root, Ident.name id, pos) in
488 let (pl, final_sub) = prefix_idents root (pos+1) sub rem in
490 | Tsig_module(id, mty, _) :: rem ->
491 let p = Pdot(root, Ident.name id, pos) in
492 let (pl, final_sub) =
493 prefix_idents root (pos+1) (Subst.add_module id p sub) rem in
495 | Tsig_modtype(id, decl) :: rem ->
496 let p = Pdot(root, Ident.name id, nopos) in
497 let (pl, final_sub) =
498 prefix_idents root pos
499 (Subst.add_modtype id (Tmty_ident p) sub) rem in
501 | Tsig_class(id, decl, _) :: rem ->
502 let p = Pdot(root, Ident.name id, pos) in
503 let (pl, final_sub) = prefix_idents root (pos + 1) sub rem in
505 | Tsig_cltype(id, decl, _) :: rem ->
506 let p = Pdot(root, Ident.name id, nopos) in
507 let (pl, final_sub) = prefix_idents root pos sub rem in
510 (* Compute structure descriptions *)
512 let rec components_of_module env sub path mty =
513 lazy(match scrape_modtype mty env with
516 { comp_values = Tbl.empty; comp_annotations = Tbl.empty;
517 comp_constrs = Tbl.empty;
518 comp_labels = Tbl.empty; comp_types = Tbl.empty;
519 comp_modules = Tbl.empty; comp_modtypes = Tbl.empty;
520 comp_components = Tbl.empty; comp_classes = Tbl.empty;
521 comp_cltypes = Tbl.empty } in
522 let (pl, sub) = prefix_idents path 0 sub sg in
525 List.iter2 (fun item path ->
527 Tsig_value(id, decl) ->
528 let decl' = Subst.value_description sub decl in
530 Tbl.add (Ident.name id) (decl', !pos) c.comp_values;
531 if !Clflags.annotations then begin
532 c.comp_annotations <-
533 Tbl.add (Ident.name id) (Annot.Iref_external, !pos)
536 begin match decl.val_kind with
537 Val_prim _ -> () | _ -> incr pos
539 | Tsig_type(id, decl, _) ->
540 let decl' = Subst.type_declaration sub decl in
542 Tbl.add (Ident.name id) (decl', nopos) c.comp_types;
544 (fun (name, descr) ->
545 c.comp_constrs <- Tbl.add name (descr, nopos) c.comp_constrs)
546 (constructors_of_type path decl');
548 (fun (name, descr) ->
549 c.comp_labels <- Tbl.add name (descr, nopos) c.comp_labels)
550 (labels_of_type path decl');
551 env := store_type_infos id path decl !env
552 | Tsig_exception(id, decl) ->
553 let decl' = Subst.exception_declaration sub decl in
554 let cstr = Datarepr.exception_descr path decl' in
556 Tbl.add (Ident.name id) (cstr, !pos) c.comp_constrs;
558 | Tsig_module(id, mty, _) ->
559 let mty' = lazy (Subst.modtype sub mty) in
561 Tbl.add (Ident.name id) (mty', !pos) c.comp_modules;
562 let comps = components_of_module !env sub path mty in
564 Tbl.add (Ident.name id) (comps, !pos) c.comp_components;
565 env := store_module id path mty !env;
567 | Tsig_modtype(id, decl) ->
568 let decl' = Subst.modtype_declaration sub decl in
570 Tbl.add (Ident.name id) (decl', nopos) c.comp_modtypes;
571 env := store_modtype id path decl !env
572 | Tsig_class(id, decl, _) ->
573 let decl' = Subst.class_declaration sub decl in
575 Tbl.add (Ident.name id) (decl', !pos) c.comp_classes;
577 | Tsig_cltype(id, decl, _) ->
578 let decl' = Subst.cltype_declaration sub decl in
580 Tbl.add (Ident.name id) (decl', !pos) c.comp_cltypes)
583 | Tmty_functor(param, ty_arg, ty_res) ->
586 (* fcomp_arg must be prefixed eagerly, because it is interpreted
587 in the outer environment, not in env *)
588 fcomp_arg = Subst.modtype sub ty_arg;
589 (* fcomp_res is prefixed lazily, because it is interpreted in env *)
593 fcomp_cache = Hashtbl.create 17 }
596 comp_values = Tbl.empty; comp_annotations = Tbl.empty;
597 comp_constrs = Tbl.empty;
598 comp_labels = Tbl.empty; comp_types = Tbl.empty;
599 comp_modules = Tbl.empty; comp_modtypes = Tbl.empty;
600 comp_components = Tbl.empty; comp_classes = Tbl.empty;
601 comp_cltypes = Tbl.empty })
603 (* Insertion of bindings by identifier + path *)
605 and store_value id path decl env =
607 values = Ident.add id (path, decl) env.values;
608 summary = Env_value(env.summary, id, decl) }
610 and store_annot id path annot env =
611 if !Clflags.annotations then
613 annotations = Ident.add id (path, annot) env.annotations }
616 and store_type id path info env =
620 (fun (name, descr) constrs ->
621 Ident.add (Ident.create name) descr constrs)
622 (constructors_of_type path info)
626 (fun (name, descr) labels ->
627 Ident.add (Ident.create name) descr labels)
628 (labels_of_type path info)
630 types = Ident.add id (path, info) env.types;
631 summary = Env_type(env.summary, id, info) }
633 and store_type_infos id path info env =
634 (* Simplified version of store_type that doesn't compute and store
635 constructor and label infos, but simply record the arity and
636 manifest-ness of the type. Used in components_of_module to
637 keep track of type abbreviations (e.g. type t = float) in the
638 computation of label representations. *)
640 types = Ident.add id (path, info) env.types;
641 summary = Env_type(env.summary, id, info) }
643 and store_exception id path decl env =
645 constrs = Ident.add id (Datarepr.exception_descr path decl) env.constrs;
646 summary = Env_exception(env.summary, id, decl) }
648 and store_module id path mty env =
650 modules = Ident.add id (path, mty) env.modules;
652 Ident.add id (path, components_of_module env Subst.identity path mty)
654 summary = Env_module(env.summary, id, mty) }
656 and store_modtype id path info env =
658 modtypes = Ident.add id (path, info) env.modtypes;
659 summary = Env_modtype(env.summary, id, info) }
661 and store_class id path desc env =
663 classes = Ident.add id (path, desc) env.classes;
664 summary = Env_class(env.summary, id, desc) }
666 and store_cltype id path desc env =
668 cltypes = Ident.add id (path, desc) env.cltypes;
669 summary = Env_cltype(env.summary, id, desc) }
671 (* Compute the components of a functor application in a path. *)
673 let components_of_functor_appl f p1 p2 =
675 Hashtbl.find f.fcomp_cache p2
677 let p = Papply(p1, p2) in
679 Subst.modtype (Subst.add_module f.fcomp_param p2 Subst.identity)
681 let comps = components_of_module f.fcomp_env f.fcomp_subst p mty in
682 Hashtbl.add f.fcomp_cache p2 comps;
685 (* Define forward functions *)
688 components_of_module' := components_of_module;
689 components_of_functor_appl' := components_of_functor_appl
691 (* Insertion of bindings by identifier *)
693 let add_value id desc env =
694 store_value id (Pident id) desc env
696 let add_annot id annot env =
697 store_annot id (Pident id) annot env
699 and add_type id info env =
700 store_type id (Pident id) info env
702 and add_exception id decl env =
703 store_exception id (Pident id) decl env
705 and add_module id mty env =
706 store_module id (Pident id) mty env
708 and add_modtype id info env =
709 store_modtype id (Pident id) info env
711 and add_class id ty env =
712 store_class id (Pident id) ty env
714 and add_cltype id ty env =
715 store_cltype id (Pident id) ty env
717 (* Insertion of bindings by name *)
719 let enter store_fun name data env =
720 let id = Ident.create name in (id, store_fun id (Pident id) data env)
722 let enter_value = enter store_value
723 and enter_type = enter store_type
724 and enter_exception = enter store_exception
725 and enter_module = enter store_module
726 and enter_modtype = enter store_modtype
727 and enter_class = enter store_class
728 and enter_cltype = enter store_cltype
730 (* Insertion of all components of a signature *)
732 let add_item comp env =
734 Tsig_value(id, decl) -> add_value id decl env
735 | Tsig_type(id, decl, _) -> add_type id decl env
736 | Tsig_exception(id, decl) -> add_exception id decl env
737 | Tsig_module(id, mty, _) -> add_module id mty env
738 | Tsig_modtype(id, decl) -> add_modtype id decl env
739 | Tsig_class(id, decl, _) -> add_class id decl env
740 | Tsig_cltype(id, decl, _) -> add_cltype id decl env
742 let rec add_signature sg env =
745 | comp :: rem -> add_signature rem (add_item comp env)
747 (* Open a signature path *)
749 let open_signature root sg env =
750 (* First build the paths and substitution *)
751 let (pl, sub) = prefix_idents root 0 Subst.identity sg in
752 (* Then enter the components in the environment after substitution *)
757 Tsig_value(id, decl) ->
758 let e1 = store_value (Ident.hide id) p
759 (Subst.value_description sub decl) env
760 in store_annot (Ident.hide id) p (Annot.Iref_external) e1
761 | Tsig_type(id, decl, _) ->
762 store_type (Ident.hide id) p
763 (Subst.type_declaration sub decl) env
764 | Tsig_exception(id, decl) ->
765 store_exception (Ident.hide id) p
766 (Subst.exception_declaration sub decl) env
767 | Tsig_module(id, mty, _) ->
768 store_module (Ident.hide id) p (Subst.modtype sub mty) env
769 | Tsig_modtype(id, decl) ->
770 store_modtype (Ident.hide id) p
771 (Subst.modtype_declaration sub decl) env
772 | Tsig_class(id, decl, _) ->
773 store_class (Ident.hide id) p
774 (Subst.class_declaration sub decl) env
775 | Tsig_cltype(id, decl, _) ->
776 store_cltype (Ident.hide id) p
777 (Subst.cltype_declaration sub decl) env)
779 { newenv with summary = Env_open(env.summary, root) }
781 (* Open a signature from a file *)
783 let open_pers_signature name env =
784 let ps = find_pers_struct name in
785 open_signature (Pident(Ident.create_persistent name)) ps.ps_sig env
787 (* Read a signature from a file *)
789 let read_signature modname filename =
790 let ps = read_pers_struct modname filename in ps.ps_sig
792 (* Return the CRC of the interface of the given compilation unit *)
794 let crc_of_unit name =
795 let ps = find_pers_struct name in
797 List.assoc name ps.ps_crcs
801 (* Return the list of imported interfaces with their CRCs *)
803 let imported_units() =
804 Consistbl.extract crc_units
806 (* Save a signature to a file *)
808 let save_signature_with_imports sg modname filename imports =
809 Btype.cleanup_abbrev ();
810 Subst.reset_for_saving ();
811 let sg = Subst.signature (Subst.for_saving Subst.identity) sg in
812 let oc = open_out_bin filename in
814 output_string oc cmi_magic_number;
815 output_value oc (modname, sg);
817 let crc = Digest.file filename in
818 let crcs = (modname, crc) :: imports in
819 output_value oc crcs;
820 let flags = if !Clflags.recursive_types then [Rectypes] else [] in
821 output_value oc flags;
823 (* Enter signature in persistent table so that imported_unit()
824 will also return its crc *)
826 components_of_module empty Subst.identity
827 (Pident(Ident.create_persistent modname)) (Tmty_signature sg) in
833 ps_filename = filename;
834 ps_flags = flags } in
835 Hashtbl.add persistent_structures modname ps;
836 Consistbl.set crc_units modname crc filename
839 remove_file filename;
842 let save_signature sg modname filename =
843 save_signature_with_imports sg modname filename (imported_units())
845 (* Make the initial environment *)
847 let initial = Predef.build_initial_env add_type add_exception empty
849 (* Return the environment summary *)
851 let summary env = env.summary
857 let report_error ppf = function
858 | Not_an_interface filename -> fprintf ppf
859 "%s@ is not a compiled interface" filename
860 | Corrupted_interface filename -> fprintf ppf
861 "Corrupted compiled interface@ %s" filename
862 | Illegal_renaming(modname, filename) -> fprintf ppf
863 "Wrong file naming: %s@ contains the compiled interface for@ %s"
865 | Inconsistent_import(name, source1, source2) -> fprintf ppf
866 "@[<hov>The files %s@ and %s@ \
867 make inconsistent assumptions@ over interface %s@]"
869 | Need_recursive_types(import, export) ->
871 "@[<hov>Unit %s imports from %s, which uses recursive types.@ %s@]"
872 import export "The compilation flag -rectypes is required"