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: typemod.ml 9079 2008-10-08 13:09:39Z doligez $ *)
15 (* Type-checking of the module language *)
27 Unbound_module of Longident.t
28 | Unbound_modtype of Longident.t
29 | Cannot_apply of module_type
30 | Not_included of Includemod.error list
31 | Cannot_eliminate_dependency of module_type
33 | Structure_expected of module_type
34 | With_no_component of Longident.t
35 | With_mismatch of Longident.t * Includemod.error list
36 | Repeated_name of string * string
37 | Non_generalizable of type_expr
38 | Non_generalizable_class of Ident.t * class_declaration
39 | Non_generalizable_module of module_type
40 | Implementation_is_required of string
41 | Interface_not_compiled of string
43 exception Error of Location.t * error
45 (* Extract a signature from a module type *)
47 let extract_sig env loc mty =
48 match Mtype.scrape env mty with
49 Tmty_signature sg -> sg
50 | _ -> raise(Error(loc, Signature_expected))
52 let extract_sig_open env loc mty =
53 match Mtype.scrape env mty with
54 Tmty_signature sg -> sg
55 | _ -> raise(Error(loc, Structure_expected mty))
57 (* Lookup the type of a module path *)
59 let type_module_path env loc lid =
61 Env.lookup_module lid env
63 raise(Error(loc, Unbound_module lid))
65 (* Record a module type *)
67 Stypes.record (Stypes.Ti_mod node);
70 (* Merge one "with" constraint in a signature *)
72 let rec add_rec_types env = function
73 Tsig_type(id, decl, Trec_next) :: rem ->
74 add_rec_types (Env.add_type id decl env) rem
77 let check_type_decl env id row_id newdecl decl rs rem =
78 let env = Env.add_type id newdecl env in
80 match row_id with None -> env | Some id -> Env.add_type id newdecl env in
81 let env = if rs = Trec_not then env else add_rec_types env rem in
82 Includemod.type_declarations env id newdecl decl
84 let merge_constraint initial_env loc sg lid constr =
85 let rec merge env sg namelist row_id =
86 match (sg, namelist, constr) with
88 raise(Error(loc, With_no_component lid))
89 | (Tsig_type(id, decl, rs) :: rem, [s],
90 Pwith_type ({ptype_kind = Ptype_abstract} as sdecl))
91 when Ident.name id = s && Typedecl.is_fixed_type sdecl ->
94 List.map (fun _ -> Btype.newgenvar()) sdecl.ptype_params;
95 type_arity = List.length sdecl.ptype_params;
96 type_kind = Type_abstract;
97 type_private = Private;
100 List.map (fun (c,n) -> (not n, not c, not c))
101 sdecl.ptype_variance }
102 and id_row = Ident.create (s^"#row") in
103 let initial_env = Env.add_type id_row decl_row initial_env in
104 let newdecl = Typedecl.transl_with_constraint
105 initial_env id (Some(Pident id_row)) sdecl in
106 check_type_decl env id row_id newdecl decl rs rem;
107 let decl_row = {decl_row with type_params = newdecl.type_params} in
108 let rs' = if rs = Trec_first then Trec_not else rs in
109 Tsig_type(id_row, decl_row, rs') :: Tsig_type(id, newdecl, rs) :: rem
110 | (Tsig_type(id, decl, rs) :: rem, [s], Pwith_type sdecl)
111 when Ident.name id = s ->
113 Typedecl.transl_with_constraint initial_env id None sdecl in
114 check_type_decl env id row_id newdecl decl rs rem;
115 Tsig_type(id, newdecl, rs) :: rem
116 | (Tsig_type(id, decl, rs) :: rem, [s], Pwith_type sdecl)
117 when Ident.name id = s ^ "#row" ->
118 merge env rem namelist (Some id)
119 | (Tsig_module(id, mty, rs) :: rem, [s], Pwith_module lid)
120 when Ident.name id = s ->
121 let (path, mty') = type_module_path initial_env loc lid in
122 let newmty = Mtype.strengthen env mty' path in
123 ignore(Includemod.modtypes env newmty mty);
124 Tsig_module(id, newmty, rs) :: rem
125 | (Tsig_module(id, mty, rs) :: rem, s :: namelist, _)
126 when Ident.name id = s ->
127 let newsg = merge env (extract_sig env loc mty) namelist None in
128 Tsig_module(id, Tmty_signature newsg, rs) :: rem
129 | (item :: rem, _, _) ->
130 item :: merge (Env.add_item item env) rem namelist row_id in
132 merge initial_env sg (Longident.flatten lid) None
133 with Includemod.Error explanation ->
134 raise(Error(loc, With_mismatch(lid, explanation)))
136 (* Add recursion flags on declarations arising from a mutually recursive
139 let map_rec fn decls rem =
142 | d1 :: dl -> fn Trec_first d1 :: map_end (fn Trec_next) dl rem
144 let rec map_rec' fn decls rem =
146 | (id,_ as d1) :: dl when Btype.is_row_name (Ident.name id) ->
147 fn Trec_not d1 :: map_rec' fn dl rem
148 | _ -> map_rec fn decls rem
150 (* Auxiliary for translating recursively-defined module types.
151 Return a module type that approximates the shape of the given module
152 type AST. Retain only module, type, and module type
153 components of signatures. For types, retain only their arity,
154 making them abstract otherwise. *)
156 let rec approx_modtype env smty =
157 match smty.pmty_desc with
160 let (path, info) = Env.lookup_modtype lid env in
163 raise(Error(smty.pmty_loc, Unbound_modtype lid))
165 | Pmty_signature ssg ->
166 Tmty_signature(approx_sig env ssg)
167 | Pmty_functor(param, sarg, sres) ->
168 let arg = approx_modtype env sarg in
169 let (id, newenv) = Env.enter_module param arg env in
170 let res = approx_modtype newenv sres in
171 Tmty_functor(id, arg, res)
172 | Pmty_with(sbody, constraints) ->
173 approx_modtype env sbody
175 and approx_sig env ssg =
179 match item.psig_desc with
180 | Psig_type sdecls ->
181 let decls = Typedecl.approx_type_decl env sdecls in
182 let rem = approx_sig env srem in
183 map_rec' (fun rs (id, info) -> Tsig_type(id, info, rs)) decls rem
184 | Psig_module(name, smty) ->
185 let mty = approx_modtype env smty in
186 let (id, newenv) = Env.enter_module name mty env in
187 Tsig_module(id, mty, Trec_not) :: approx_sig newenv srem
188 | Psig_recmodule sdecls ->
192 (Ident.create name, approx_modtype env smty))
195 List.fold_left (fun env (id, mty) -> Env.add_module id mty env)
197 map_rec (fun rs (id, mty) -> Tsig_module(id, mty, rs)) decls
198 (approx_sig newenv srem)
199 | Psig_modtype(name, sinfo) ->
200 let info = approx_modtype_info env sinfo in
201 let (id, newenv) = Env.enter_modtype name info env in
202 Tsig_modtype(id, info) :: approx_sig newenv srem
204 let (path, mty) = type_module_path env item.psig_loc lid in
205 let sg = extract_sig_open env item.psig_loc mty in
206 let newenv = Env.open_signature path sg env in
207 approx_sig newenv srem
208 | Psig_include smty ->
209 let mty = approx_modtype env smty in
210 let sg = Subst.signature Subst.identity
211 (extract_sig env smty.pmty_loc mty) in
212 let newenv = Env.add_signature sg env in
213 sg @ approx_sig newenv srem
214 | Psig_class sdecls | Psig_class_type sdecls ->
215 let decls = Typeclass.approx_class_declarations env sdecls in
216 let rem = approx_sig env srem in
219 (fun rs (i1, d1, i2, d2, i3, d3) ->
220 [Tsig_cltype(i1, d1, rs);
221 Tsig_type(i2, d2, rs);
222 Tsig_type(i3, d3, rs)])
227 and approx_modtype_info env sinfo =
231 | Pmodtype_manifest smty ->
232 Tmodtype_manifest(approx_modtype env smty)
234 (* Additional validity checks on type definitions arising from
237 let check_recmod_typedecls env sdecls decls =
238 let recmod_ids = List.map fst decls in
240 (fun (_, smty) (id, mty) ->
243 Typedecl.check_recmod_typedecl env smty.pmty_loc recmod_ids
244 path (Env.find_type path env))
245 (Mtype.type_paths env (Pident id) mty))
248 (* Auxiliaries for checking uniqueness of names in signatures and structures *)
250 module StringSet = Set.Make(struct type t = string let compare = compare end)
252 let check cl loc set_ref name =
253 if StringSet.mem name !set_ref
254 then raise(Error(loc, Repeated_name(cl, name)))
255 else set_ref := StringSet.add name !set_ref
257 let check_sig_item type_names module_names modtype_names loc = function
258 Tsig_type(id, _, _) ->
259 check "type" loc type_names (Ident.name id)
260 | Tsig_module(id, _, _) ->
261 check "module" loc module_names (Ident.name id)
262 | Tsig_modtype(id, _) ->
263 check "module type" loc modtype_names (Ident.name id)
266 (* Check and translate a module type expression *)
268 let rec transl_modtype env smty =
269 match smty.pmty_desc with
272 let (path, info) = Env.lookup_modtype lid env in
275 raise(Error(smty.pmty_loc, Unbound_modtype lid))
277 | Pmty_signature ssg ->
278 Tmty_signature(transl_signature env ssg)
279 | Pmty_functor(param, sarg, sres) ->
280 let arg = transl_modtype env sarg in
281 let (id, newenv) = Env.enter_module param arg env in
282 let res = transl_modtype newenv sres in
283 Tmty_functor(id, arg, res)
284 | Pmty_with(sbody, constraints) ->
285 let body = transl_modtype env sbody in
286 let init_sg = extract_sig env sbody.pmty_loc body in
289 (fun sg (lid, sdecl) ->
290 merge_constraint env smty.pmty_loc sg lid sdecl)
291 init_sg constraints in
292 Mtype.freshen (Tmty_signature final_sg)
294 and transl_signature env sg =
295 let type_names = ref StringSet.empty
296 and module_names = ref StringSet.empty
297 and modtype_names = ref StringSet.empty in
298 let rec transl_sig env sg =
299 Ctype.init_def(Ident.current_time());
303 match item.psig_desc with
304 | Psig_value(name, sdesc) ->
305 let desc = Typedecl.transl_value_decl env sdesc in
306 let (id, newenv) = Env.enter_value name desc env in
307 let rem = transl_sig newenv srem in
308 Tsig_value(id, desc) :: rem
309 | Psig_type sdecls ->
311 (fun (name, decl) -> check "type" item.psig_loc type_names name)
313 let (decls, newenv) = Typedecl.transl_type_decl env sdecls in
314 let rem = transl_sig newenv srem in
315 map_rec' (fun rs (id, info) -> Tsig_type(id, info, rs)) decls rem
316 | Psig_exception(name, sarg) ->
317 let arg = Typedecl.transl_exception env sarg in
318 let (id, newenv) = Env.enter_exception name arg env in
319 let rem = transl_sig newenv srem in
320 Tsig_exception(id, arg) :: rem
321 | Psig_module(name, smty) ->
322 check "module" item.psig_loc module_names name;
323 let mty = transl_modtype env smty in
324 let (id, newenv) = Env.enter_module name mty env in
325 let rem = transl_sig newenv srem in
326 Tsig_module(id, mty, Trec_not) :: rem
327 | Psig_recmodule sdecls ->
330 check "module" item.psig_loc module_names name)
332 let (decls, newenv) =
333 transl_recmodule_modtypes item.psig_loc env sdecls in
334 let rem = transl_sig newenv srem in
335 map_rec (fun rs (id, mty) -> Tsig_module(id, mty, rs)) decls rem
336 | Psig_modtype(name, sinfo) ->
337 check "module type" item.psig_loc modtype_names name;
338 let info = transl_modtype_info env sinfo in
339 let (id, newenv) = Env.enter_modtype name info env in
340 let rem = transl_sig newenv srem in
341 Tsig_modtype(id, info) :: rem
343 let (path, mty) = type_module_path env item.psig_loc lid in
344 let sg = extract_sig_open env item.psig_loc mty in
345 let newenv = Env.open_signature path sg env in
346 transl_sig newenv srem
347 | Psig_include smty ->
348 let mty = transl_modtype env smty in
349 let sg = Subst.signature Subst.identity
350 (extract_sig env smty.pmty_loc mty) in
352 (check_sig_item type_names module_names modtype_names
355 let newenv = Env.add_signature sg env in
356 let rem = transl_sig newenv srem in
360 (fun {pci_name = name} ->
361 check "type" item.psig_loc type_names name)
363 let (classes, newenv) = Typeclass.class_descriptions env cl in
364 let rem = transl_sig newenv srem in
367 (fun rs (i, d, i', d', i'', d'', i''', d''', _, _, _) ->
368 [Tsig_class(i, d, rs);
369 Tsig_cltype(i', d', rs);
370 Tsig_type(i'', d'', rs);
371 Tsig_type(i''', d''', rs)])
373 | Psig_class_type cl ->
375 (fun {pci_name = name} ->
376 check "type" item.psig_loc type_names name)
378 let (classes, newenv) = Typeclass.class_type_declarations env cl in
379 let rem = transl_sig newenv srem in
382 (fun rs (i, d, i', d', i'', d'') ->
383 [Tsig_cltype(i, d, rs);
384 Tsig_type(i', d', rs);
385 Tsig_type(i'', d'', rs)])
389 and transl_modtype_info env sinfo =
393 | Pmodtype_manifest smty ->
394 Tmodtype_manifest(transl_modtype env smty)
396 and transl_recmodule_modtypes loc env sdecls =
399 (fun env (id, mty) -> Env.add_module id mty env)
401 let transition env_c curr =
403 (fun (_, smty) (id, mty) -> (id, transl_modtype env_c smty))
408 (Ident.create name, approx_modtype env smty))
410 let env0 = make_env init in
411 let dcl1 = transition env0 init in
412 let env1 = make_env dcl1 in
413 check_recmod_typedecls env1 sdecls dcl1;
414 let dcl2 = transition env1 dcl1 in
418 Format.printf "%a: %a@." Printtyp.ident id Printtyp.modtype mty)
421 let env2 = make_env dcl2 in
422 check_recmod_typedecls env2 sdecls dcl2;
425 (* Try to convert a module expression to a module path. *)
429 let rec path_of_module mexp =
430 match mexp.mod_desc with
432 | Tmod_apply(funct, arg, coercion) ->
433 Papply(path_of_module funct, path_of_module arg)
434 | _ -> raise Not_a_path
436 (* Check that all core type schemes in a structure are closed *)
438 let rec closed_modtype = function
440 | Tmty_signature sg -> List.for_all closed_signature_item sg
441 | Tmty_functor(id, param, body) -> closed_modtype body
443 and closed_signature_item = function
444 Tsig_value(id, desc) -> Ctype.closed_schema desc.val_type
445 | Tsig_module(id, mty, _) -> closed_modtype mty
448 let check_nongen_scheme env = function
449 Tstr_value(rec_flag, pat_exp_list) ->
452 if not (Ctype.closed_schema exp.exp_type) then
453 raise(Error(exp.exp_loc, Non_generalizable exp.exp_type)))
455 | Tstr_module(id, md) ->
456 if not (closed_modtype md.mod_type) then
457 raise(Error(md.mod_loc, Non_generalizable_module md.mod_type))
460 let check_nongen_schemes env str =
461 List.iter (check_nongen_scheme env) str
463 (* Extract the list of "value" identifiers bound by a signature.
464 "Value" identifiers are identifiers for signature components that
465 correspond to a run-time value: values, exceptions, modules, classes.
466 Note: manifest primitives do not correspond to a run-time value! *)
468 let rec bound_value_identifiers = function
470 | Tsig_value(id, {val_kind = Val_reg}) :: rem ->
471 id :: bound_value_identifiers rem
472 | Tsig_exception(id, decl) :: rem -> id :: bound_value_identifiers rem
473 | Tsig_module(id, mty, _) :: rem -> id :: bound_value_identifiers rem
474 | Tsig_class(id, decl, _) :: rem -> id :: bound_value_identifiers rem
475 | _ :: rem -> bound_value_identifiers rem
477 (* Helpers for typing recursive modules *)
479 let anchor_submodule name anchor =
480 match anchor with None -> None | Some p -> Some(Pdot(p, name, nopos))
481 let anchor_recmodule id anchor =
484 let enrich_type_decls anchor decls oldenv newenv =
491 Mtype.enrich_typedecl oldenv (Pdot(p, Ident.name id, nopos)) info
493 Env.add_type id info' e)
496 let enrich_module_type anchor name mty env =
499 | Some p -> Mtype.enrich_modtype env (Pdot(p, name, nopos)) mty
501 let check_recmodule_inclusion env bindings =
502 (* PR#4450, PR#4470: consider
503 module rec X : DECL = MOD where MOD has inferred type ACTUAL
504 The "natural" typing condition
505 E, X: ACTUAL |- ACTUAL <: DECL
506 leads to circularities through manifest types.
507 Instead, we "unroll away" the potential circularities a finite number
508 of times. The (weaker) condition we implement is:
511 X2: ACTUAL{X <- X1}/X1
513 Xn: ACTUAL{X <- X(n-1)}/X(n-1)
514 |- ACTUAL{X <- Xn}/Xn <: DECL{X <- Xn}
515 so that manifest types rooted at X(n+1) are expanded in terms of X(n),
516 avoiding circularities. The strengthenings ensure that
517 Xn.t = X(n-1).t = ... = X2.t = X1.t.
518 N can be chosen arbitrarily; larger values of N result in more
519 recursive definitions being accepted. A good choice appears to be
520 the number of mutually recursive declarations. *)
522 let subst_and_strengthen env s id mty =
523 Mtype.strengthen env (Subst.modtype s mty)
524 (Subst.module_path s (Pident id)) in
526 let rec check_incl first_time n env s =
528 (* Generate fresh names Y_i for the rec. bound module idents X_i *)
531 (fun (id, mty_decl, modl, mty_actual) ->
532 (id, Ident.rename id, mty_actual))
534 (* Enter the Y_i in the environment with their actual types substituted
535 by the input substitution s *)
538 (fun env (id, id', mty_actual) ->
542 else subst_and_strengthen env s id mty_actual in
543 Env.add_module id' mty_actual' env)
545 (* Build the output substitution Y_i <- X_i *)
548 (fun s (id, id', mty_actual) ->
549 Subst.add_module id (Pident id') s)
550 Subst.identity bindings1 in
551 (* Recurse with env' and s' *)
552 check_incl false (n-1) env' s'
554 (* Base case: check inclusion of s(mty_actual) in s(mty_decl)
555 and insert coercion if needed *)
556 let check_inclusion (id, mty_decl, modl, mty_actual) =
557 let mty_decl' = Subst.modtype s mty_decl
558 and mty_actual' = subst_and_strengthen env s id mty_actual in
561 Includemod.modtypes env mty_actual' mty_decl'
562 with Includemod.Error msg ->
563 raise(Error(modl.mod_loc, Not_included msg)) in
565 { mod_desc = Tmod_constraint(modl, mty_decl, coercion);
568 mod_loc = modl.mod_loc } in
570 List.map check_inclusion bindings
572 in check_incl true (List.length bindings) env Subst.identity
574 (* Type a module value expression *)
576 let rec type_module anchor env smod =
577 match smod.pmod_desc with
579 let (path, mty) = type_module_path env smod.pmod_loc lid in
580 rm { mod_desc = Tmod_ident path;
581 mod_type = Mtype.strengthen env mty path;
583 mod_loc = smod.pmod_loc }
584 | Pmod_structure sstr ->
585 let (str, sg, finalenv) = type_structure anchor env sstr smod.pmod_loc in
586 rm { mod_desc = Tmod_structure str;
587 mod_type = Tmty_signature sg;
589 mod_loc = smod.pmod_loc }
590 | Pmod_functor(name, smty, sbody) ->
591 let mty = transl_modtype env smty in
592 let (id, newenv) = Env.enter_module name mty env in
593 let body = type_module None newenv sbody in
594 rm { mod_desc = Tmod_functor(id, mty, body);
595 mod_type = Tmty_functor(id, mty, body.mod_type);
597 mod_loc = smod.pmod_loc }
598 | Pmod_apply(sfunct, sarg) ->
599 let funct = type_module None env sfunct in
600 let arg = type_module None env sarg in
601 begin match Mtype.scrape env funct.mod_type with
602 Tmty_functor(param, mty_param, mty_res) as mty_functor ->
605 Includemod.modtypes env arg.mod_type mty_param
606 with Includemod.Error msg ->
607 raise(Error(sarg.pmod_loc, Not_included msg)) in
610 let path = path_of_module arg in
611 Subst.modtype (Subst.add_module param path Subst.identity)
615 Mtype.nondep_supertype
616 (Env.add_module param arg.mod_type env) param mty_res
618 raise(Error(smod.pmod_loc,
619 Cannot_eliminate_dependency mty_functor)) in
620 rm { mod_desc = Tmod_apply(funct, arg, coercion);
623 mod_loc = smod.pmod_loc }
625 raise(Error(sfunct.pmod_loc, Cannot_apply funct.mod_type))
627 | Pmod_constraint(sarg, smty) ->
628 let arg = type_module anchor env sarg in
629 let mty = transl_modtype env smty in
632 Includemod.modtypes env arg.mod_type mty
633 with Includemod.Error msg ->
634 raise(Error(sarg.pmod_loc, Not_included msg)) in
635 rm { mod_desc = Tmod_constraint(arg, mty, coercion);
638 mod_loc = smod.pmod_loc }
640 and type_structure anchor env sstr scope =
641 let type_names = ref StringSet.empty
642 and module_names = ref StringSet.empty
643 and modtype_names = ref StringSet.empty in
644 let rec type_struct env sstr =
645 Ctype.init_def(Ident.current_time());
649 | {pstr_desc = Pstr_eval sexpr} :: srem ->
650 let expr = Typecore.type_expression env sexpr in
651 let (str_rem, sig_rem, final_env) = type_struct env srem in
652 (Tstr_eval expr :: str_rem, sig_rem, final_env)
653 | {pstr_desc = Pstr_value(rec_flag, sdefs); pstr_loc = loc} :: srem ->
656 | Recursive -> Some (Annot.Idef {scope with
657 Location.loc_start = loc.Location.loc_start})
659 let start = match srem with
660 | [] -> loc.Location.loc_end
661 | {pstr_loc = loc2} :: _ -> loc2.Location.loc_start
662 in Some (Annot.Idef {scope with Location.loc_start = start})
666 Typecore.type_binding env rec_flag sdefs scope in
667 let (str_rem, sig_rem, final_env) = type_struct newenv srem in
668 let bound_idents = let_bound_idents defs in
669 let make_sig_value id =
670 Tsig_value(id, Env.find_value (Pident id) newenv) in
671 (Tstr_value(rec_flag, defs) :: str_rem,
672 map_end make_sig_value bound_idents sig_rem,
674 | {pstr_desc = Pstr_primitive(name, sdesc)} :: srem ->
675 let desc = Typedecl.transl_value_decl env sdesc in
676 let (id, newenv) = Env.enter_value name desc env in
677 let (str_rem, sig_rem, final_env) = type_struct newenv srem in
678 (Tstr_primitive(id, desc) :: str_rem,
679 Tsig_value(id, desc) :: sig_rem,
681 | {pstr_desc = Pstr_type sdecls; pstr_loc = loc} :: srem ->
683 (fun (name, decl) -> check "type" loc type_names name)
685 let (decls, newenv) = Typedecl.transl_type_decl env sdecls in
687 enrich_type_decls anchor decls env newenv in
688 let (str_rem, sig_rem, final_env) = type_struct newenv' srem in
689 (Tstr_type decls :: str_rem,
690 map_rec' (fun rs (id, info) -> Tsig_type(id, info, rs)) decls sig_rem,
692 | {pstr_desc = Pstr_exception(name, sarg)} :: srem ->
693 let arg = Typedecl.transl_exception env sarg in
694 let (id, newenv) = Env.enter_exception name arg env in
695 let (str_rem, sig_rem, final_env) = type_struct newenv srem in
696 (Tstr_exception(id, arg) :: str_rem,
697 Tsig_exception(id, arg) :: sig_rem,
699 | {pstr_desc = Pstr_exn_rebind(name, longid); pstr_loc = loc} :: srem ->
700 let (path, arg) = Typedecl.transl_exn_rebind env loc longid in
701 let (id, newenv) = Env.enter_exception name arg env in
702 let (str_rem, sig_rem, final_env) = type_struct newenv srem in
703 (Tstr_exn_rebind(id, path) :: str_rem,
704 Tsig_exception(id, arg) :: sig_rem,
706 | {pstr_desc = Pstr_module(name, smodl); pstr_loc = loc} :: srem ->
707 check "module" loc module_names name;
708 let modl = type_module (anchor_submodule name anchor) env smodl in
709 let mty = enrich_module_type anchor name modl.mod_type env in
710 let (id, newenv) = Env.enter_module name mty env in
711 let (str_rem, sig_rem, final_env) = type_struct newenv srem in
712 (Tstr_module(id, modl) :: str_rem,
713 Tsig_module(id, modl.mod_type, Trec_not) :: sig_rem,
715 | {pstr_desc = Pstr_recmodule sbind; pstr_loc = loc} :: srem ->
717 (fun (name, _, _) -> check "module" loc module_names name)
719 let (decls, newenv) =
720 transl_recmodule_modtypes loc env
721 (List.map (fun (name, smty, smodl) -> (name, smty)) sbind) in
724 (fun (id, mty) (name, smty, smodl) ->
726 type_module (anchor_recmodule id anchor) newenv smodl in
728 enrich_module_type anchor (Ident.name id) modl.mod_type newenv in
729 (id, mty, modl, mty'))
732 check_recmodule_inclusion newenv bindings1 in
733 let (str_rem, sig_rem, final_env) = type_struct newenv srem in
734 (Tstr_recmodule bindings2 :: str_rem,
735 map_rec (fun rs (id, modl) -> Tsig_module(id, modl.mod_type, rs))
738 | {pstr_desc = Pstr_modtype(name, smty); pstr_loc = loc} :: srem ->
739 check "module type" loc modtype_names name;
740 let mty = transl_modtype env smty in
741 let (id, newenv) = Env.enter_modtype name (Tmodtype_manifest mty) env in
742 let (str_rem, sig_rem, final_env) = type_struct newenv srem in
743 (Tstr_modtype(id, mty) :: str_rem,
744 Tsig_modtype(id, Tmodtype_manifest mty) :: sig_rem,
746 | {pstr_desc = Pstr_open lid; pstr_loc = loc} :: srem ->
747 let (path, mty) = type_module_path env loc lid in
748 let sg = extract_sig_open env loc mty in
749 type_struct (Env.open_signature path sg env) srem
750 | {pstr_desc = Pstr_class cl; pstr_loc = loc} :: srem ->
752 (fun {pci_name = name} -> check "type" loc type_names name)
754 let (classes, new_env) = Typeclass.class_declarations env cl in
755 let (str_rem, sig_rem, final_env) = type_struct new_env srem in
757 (List.map (fun (i, d, _,_,_,_,_,_, s, m, c) ->
758 let vf = if d.cty_new = None then Virtual else Concrete in
759 (i, s, m, c, vf)) classes) ::
761 (List.map (fun (_,_, i, d, _,_,_,_,_,_,_) -> (i, d)) classes) ::
763 (List.map (fun (_,_,_,_, i, d, _,_,_,_,_) -> (i, d)) classes) ::
765 (List.map (fun (_,_,_,_,_,_, i, d, _,_,_) -> (i, d)) classes) ::
769 (fun rs (i, d, i', d', i'', d'', i''', d''', _, _, _) ->
770 [Tsig_class(i, d, rs);
771 Tsig_cltype(i', d', rs);
772 Tsig_type(i'', d'', rs);
773 Tsig_type(i''', d''', rs)])
776 | {pstr_desc = Pstr_class_type cl; pstr_loc = loc} :: srem ->
778 (fun {pci_name = name} -> check "type" loc type_names name)
780 let (classes, new_env) = Typeclass.class_type_declarations env cl in
781 let (str_rem, sig_rem, final_env) = type_struct new_env srem in
783 (List.map (fun (i, d, _, _, _, _) -> (i, d)) classes) ::
785 (List.map (fun (_, _, i, d, _, _) -> (i, d)) classes) ::
787 (List.map (fun (_, _, _, _, i, d) -> (i, d)) classes) ::
791 (fun rs (i, d, i', d', i'', d'') ->
792 [Tsig_cltype(i, d, rs);
793 Tsig_type(i', d', rs);
794 Tsig_type(i'', d'', rs)])
797 | {pstr_desc = Pstr_include smodl; pstr_loc = loc} :: srem ->
798 let modl = type_module None env smodl in
799 (* Rename all identifiers bound by this signature to avoid clashes *)
800 let sg = Subst.signature Subst.identity
801 (extract_sig_open env smodl.pmod_loc modl.mod_type) in
803 (check_sig_item type_names module_names modtype_names loc) sg;
804 let new_env = Env.add_signature sg env in
805 let (str_rem, sig_rem, final_env) = type_struct new_env srem in
806 (Tstr_include (modl, bound_value_identifiers sg) :: str_rem,
810 if !Clflags.annotations
811 then List.iter (function {pstr_loc = l} -> Stypes.record_phrase l) sstr;
814 let type_module = type_module None
815 let type_structure = type_structure None
817 (* Fill in the forward declaration *)
819 Typecore.type_module := type_module
821 (* Normalize types in a signature *)
823 let rec normalize_modtype env = function
825 | Tmty_signature sg -> normalize_signature env sg
826 | Tmty_functor(id, param, body) -> normalize_modtype env body
828 and normalize_signature env = List.iter (normalize_signature_item env)
830 and normalize_signature_item env = function
831 Tsig_value(id, desc) -> Ctype.normalize_type env desc.val_type
832 | Tsig_module(id, mty, _) -> normalize_modtype env mty
835 (* Simplify multiple specifications of a value or an exception in a signature.
836 (Other signature components, e.g. types, modules, etc, are checked for
837 name uniqueness.) If multiple specifications with the same name,
838 keep only the last (rightmost) one. *)
840 let rec simplify_modtype mty =
842 Tmty_ident path -> mty
843 | Tmty_functor(id, arg, res) -> Tmty_functor(id, arg, simplify_modtype res)
844 | Tmty_signature sg -> Tmty_signature(simplify_signature sg)
846 and simplify_signature sg =
847 let rec simplif val_names exn_names res = function
849 | (Tsig_value(id, descr) as component) :: sg ->
850 let name = Ident.name id in
851 simplif (StringSet.add name val_names) exn_names
852 (if StringSet.mem name val_names then res else component :: res)
854 | (Tsig_exception(id, decl) as component) :: sg ->
855 let name = Ident.name id in
856 simplif val_names (StringSet.add name exn_names)
857 (if StringSet.mem name exn_names then res else component :: res)
859 | Tsig_module(id, mty, rs) :: sg ->
860 simplif val_names exn_names
861 (Tsig_module(id, simplify_modtype mty, rs) :: res) sg
863 simplif val_names exn_names (component :: res) sg
865 simplif StringSet.empty StringSet.empty [] (List.rev sg)
867 (* Typecheck an implementation file *)
869 let type_implementation sourcefile outputprefix modulename initial_env ast =
870 Typecore.reset_delayed_checks ();
871 let (str, sg, finalenv) = type_structure initial_env ast Location.none in
872 let simple_sg = simplify_signature sg in
873 Typecore.force_delayed_checks ();
874 if !Clflags.print_types then begin
875 fprintf std_formatter "%a@." Printtyp.signature simple_sg;
876 (str, Tcoerce_none) (* result is ignored by Compile.implementation *)
879 Misc.chop_extension_if_any sourcefile ^ !Config.interface_suffix in
880 if Sys.file_exists sourceintf then begin
883 find_in_path_uncap !Config.load_path (modulename ^ ".cmi")
885 raise(Error(Location.none, Interface_not_compiled sourceintf)) in
886 let dclsig = Env.read_signature modulename intf_file in
887 let coercion = Includemod.compunit sourcefile sg intf_file dclsig in
890 check_nongen_schemes finalenv str;
891 normalize_signature finalenv simple_sg;
893 Includemod.compunit sourcefile sg
894 "(inferred signature)" simple_sg in
895 if not !Clflags.dont_write_files then
896 Env.save_signature simple_sg modulename (outputprefix ^ ".cmi");
901 (* "Packaging" of several compilation units into one unit
902 having them as sub-modules. *)
904 let rec package_signatures subst = function
906 | (name, sg) :: rem ->
907 let sg' = Subst.signature subst sg in
908 let oldid = Ident.create_persistent name
909 and newid = Ident.create name in
910 Tsig_module(newid, Tmty_signature sg', Trec_not) ::
911 package_signatures (Subst.add_module oldid (Pident newid) subst) rem
913 let package_units objfiles cmifile modulename =
914 (* Read the signatures of the units *)
918 let pref = chop_extensions f in
919 let modname = String.capitalize(Filename.basename pref) in
920 let sg = Env.read_signature modname (pref ^ ".cmi") in
921 if Filename.check_suffix f ".cmi" &&
922 not(Mtype.no_code_needed_sig Env.initial sg)
923 then raise(Error(Location.none, Implementation_is_required f));
924 (modname, Env.read_signature modname (pref ^ ".cmi")))
926 (* Compute signature of packaged unit *)
928 let sg = package_signatures Subst.identity units in
929 (* See if explicit interface is provided *)
931 chop_extension_if_any cmifile ^ !Config.interface_suffix in
932 if Sys.file_exists mlifile then begin
933 if not (Sys.file_exists cmifile) then begin
934 raise(Error(Location.in_file mlifile, Interface_not_compiled mlifile))
936 let dclsig = Env.read_signature modulename cmifile in
937 Includemod.compunit "(obtained by packing)" sg mlifile dclsig
939 (* Determine imports *)
940 let unit_names = List.map fst units in
943 (fun (name, crc) -> not (List.mem name unit_names))
944 (Env.imported_units()) in
945 (* Write packaged signature *)
946 Env.save_signature_with_imports sg modulename cmifile imports;
954 let report_error ppf = function
955 | Unbound_module lid -> fprintf ppf "Unbound module %a" longident lid
956 | Unbound_modtype lid -> fprintf ppf "Unbound module type %a" longident lid
957 | Cannot_apply mty ->
959 "@[This module is not a functor; it has type@ %a@]" modtype mty
960 | Not_included errs ->
962 "@[<v>Signature mismatch:@ %a@]" Includemod.report_error errs
963 | Cannot_eliminate_dependency mty ->
965 "@[This functor has type@ %a@ \
966 The parameter cannot be eliminated in the result type.@ \
967 Please bind the argument to a module identifier.@]" modtype mty
968 | Signature_expected -> fprintf ppf "This module type is not a signature"
969 | Structure_expected mty ->
971 "@[This module is not a structure; it has type@ %a" modtype mty
972 | With_no_component lid ->
974 "@[The signature constrained by `with' has no component named %a@]"
976 | With_mismatch(lid, explanation) ->
979 @[In this `with' constraint, the new definition of %a@ \
980 does not match its original definition@ \
981 in the constrained signature:@]@ \
983 longident lid Includemod.report_error explanation
984 | Repeated_name(kind, name) ->
986 "@[Multiple definition of the %s name %s.@ \
987 Names must be unique in a given structure or signature.@]" kind name
988 | Non_generalizable typ ->
990 "@[The type of this expression,@ %a,@ \
991 contains type variables that cannot be generalized@]" type_scheme typ
992 | Non_generalizable_class (id, desc) ->
994 "@[The type of this class,@ %a,@ \
995 contains type variables that cannot be generalized@]"
996 (class_declaration id) desc
997 | Non_generalizable_module mty ->
999 "@[The type of this module,@ %a,@ \
1000 contains type variables that cannot be generalized@]" modtype mty
1001 | Implementation_is_required intf_name ->
1003 "@[The interface %s@ declares values, not just types.@ \
1004 An implementation must be provided.@]" intf_name
1005 | Interface_not_compiled intf_name ->
1007 "@[Could not find the .cmi file for interface@ %s.@]" intf_name