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: mtype.ml 9291 2009-06-08 02:35:15Z garrigue $ *)
15 (* Operations on module types *)
22 let rec scrape env mty =
26 scrape env (Env.find_modtype_expansion p env)
33 Subst.modtype Subst.identity mty
35 let rec strengthen env mty p =
36 match scrape env mty with
38 Tmty_signature(strengthen_sig env sg p)
39 | Tmty_functor(param, arg, res) ->
40 Tmty_functor(param, arg, strengthen env res (Papply(p, Pident param)))
44 and strengthen_sig env sg p =
47 | (Tsig_value(id, desc) as sigelt) :: rem ->
48 sigelt :: strengthen_sig env rem p
49 | Tsig_type(id, decl, rs) :: rem ->
51 match decl.type_manifest with
52 Some ty when decl.type_private = Public -> decl
55 Some(Btype.newgenty(Tconstr(Pdot(p, Ident.name id, nopos),
56 decl.type_params, ref Mnil))) in
57 if decl.type_kind = Type_abstract then
58 { decl with type_private = Public; type_manifest = manif }
60 { decl with type_manifest = manif }
62 Tsig_type(id, newdecl, rs) :: strengthen_sig env rem p
63 | (Tsig_exception(id, d) as sigelt) :: rem ->
64 sigelt :: strengthen_sig env rem p
65 | Tsig_module(id, mty, rs) :: rem ->
66 Tsig_module(id, strengthen env mty (Pdot(p, Ident.name id, nopos)), rs)
67 :: strengthen_sig (Env.add_module id mty env) rem p
68 (* Need to add the module in case it defines manifest module types *)
69 | Tsig_modtype(id, decl) :: rem ->
73 Tmodtype_manifest(Tmty_ident(Pdot(p, Ident.name id, nopos)))
74 | Tmodtype_manifest _ ->
76 Tsig_modtype(id, newdecl) ::
77 strengthen_sig (Env.add_modtype id decl env) rem p
78 (* Need to add the module type in case it is manifest *)
79 | (Tsig_class(id, decl, rs) as sigelt) :: rem ->
80 sigelt :: strengthen_sig env rem p
81 | (Tsig_cltype(id, decl, rs) as sigelt) :: rem ->
82 sigelt :: strengthen_sig env rem p
84 (* In nondep_supertype, env is only used for the type it assigns to id.
85 Hence there is no need to keep env up-to-date by adding the bindings
88 type variance = Co | Contra | Strict
90 let nondep_supertype env mid mty =
92 let rec nondep_mty va mty =
95 if Path.isfree mid p then
96 nondep_mty va (Env.find_modtype_expansion p env)
98 | Tmty_signature sg ->
99 Tmty_signature(nondep_sig va sg)
100 | Tmty_functor(param, arg, res) ->
102 match va with Co -> Contra | Contra -> Co | Strict -> Strict in
103 Tmty_functor(param, nondep_mty var_inv arg, nondep_mty va res)
105 and nondep_sig va = function
108 let rem' = nondep_sig va rem in
111 Tsig_value(id, {val_type = Ctype.nondep_type env mid d.val_type;
112 val_kind = d.val_kind}) :: rem'
113 | Tsig_type(id, d, rs) ->
114 Tsig_type(id, Ctype.nondep_type_decl env mid id (va = Co) d, rs)
116 | Tsig_exception(id, d) ->
117 Tsig_exception(id, List.map (Ctype.nondep_type env mid) d) :: rem'
118 | Tsig_module(id, mty, rs) ->
119 Tsig_module(id, nondep_mty va mty, rs) :: rem'
120 | Tsig_modtype(id, d) ->
122 Tsig_modtype(id, nondep_modtype_decl d) :: rem'
125 Co -> Tsig_modtype(id, Tmodtype_abstract) :: rem'
126 | _ -> raise Not_found
128 | Tsig_class(id, d, rs) ->
129 Tsig_class(id, Ctype.nondep_class_declaration env mid d, rs)
131 | Tsig_cltype(id, d, rs) ->
132 Tsig_cltype(id, Ctype.nondep_cltype_declaration env mid d, rs)
135 and nondep_modtype_decl = function
136 Tmodtype_abstract -> Tmodtype_abstract
137 | Tmodtype_manifest mty -> Tmodtype_manifest(nondep_mty Strict mty)
142 let enrich_typedecl env p decl =
143 match decl.type_manifest with
147 let orig_decl = Env.find_type p env in
148 if orig_decl.type_arity <> decl.type_arity
150 else {decl with type_manifest =
151 Some(Btype.newgenty(Tconstr(p, decl.type_params, ref Mnil)))}
155 let rec enrich_modtype env p mty =
158 Tmty_signature(List.map (enrich_item env p) sg)
162 and enrich_item env p = function
163 Tsig_type(id, decl, rs) ->
165 enrich_typedecl env (Pdot(p, Ident.name id, nopos)) decl, rs)
166 | Tsig_module(id, mty, rs) ->
168 enrich_modtype env (Pdot(p, Ident.name id, nopos)) mty, rs)
171 let rec type_paths env p mty =
172 match scrape env mty with
174 | Tmty_signature sg -> type_paths_sig env p 0 sg
175 | Tmty_functor(param, arg, res) -> []
177 and type_paths_sig env p pos sg =
180 | Tsig_value(id, decl) :: rem ->
181 let pos' = match decl.val_kind with Val_prim _ -> pos | _ -> pos + 1 in
182 type_paths_sig env p pos' rem
183 | Tsig_type(id, decl, _) :: rem ->
184 Pdot(p, Ident.name id, nopos) :: type_paths_sig env p pos rem
185 | Tsig_module(id, mty, _) :: rem ->
186 type_paths env (Pdot(p, Ident.name id, pos)) mty @
187 type_paths_sig (Env.add_module id mty env) p (pos+1) rem
188 | Tsig_modtype(id, decl) :: rem ->
189 type_paths_sig (Env.add_modtype id decl env) p pos rem
190 | (Tsig_exception _ | Tsig_class _) :: rem ->
191 type_paths_sig env p (pos+1) rem
192 | (Tsig_cltype _) :: rem ->
193 type_paths_sig env p pos rem
195 let rec no_code_needed env mty =
196 match scrape env mty with
197 Tmty_ident p -> false
198 | Tmty_signature sg -> no_code_needed_sig env sg
199 | Tmty_functor(_, _, _) -> false
201 and no_code_needed_sig env sg =
204 | Tsig_value(id, decl) :: rem ->
205 begin match decl.val_kind with
206 | Val_prim _ -> no_code_needed_sig env rem
209 | Tsig_module(id, mty, _) :: rem ->
210 no_code_needed env mty &&
211 no_code_needed_sig (Env.add_module id mty env) rem
212 | (Tsig_type _ | Tsig_modtype _ | Tsig_cltype _) :: rem ->
213 no_code_needed_sig env rem
214 | (Tsig_exception _ | Tsig_class _) :: rem ->