summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlain Frisch <alain@frisch.fr>2010-07-09 08:43:24 +0000
committerAlain Frisch <alain@frisch.fr>2010-07-09 08:43:24 +0000
commit3a01271dcbbc8b50ad7b463b425f92921f69bf74 (patch)
treebfb5dc7c25ee2aa35ca6c14713a0d3bceb4ba968
parent3049ff108d3982a4335c0846c0efe5dfaf5a9e9b (diff)
downloadocaml-3a01271dcbbc8b50ad7b463b425f92921f69bf74.tar.gz
PR#5096: overly restrictive value restriction check for first class modules.
git-svn-id: http://caml.inria.fr/svn/ocaml/version/3.12@10623 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r--typing/typecore.ml21
1 files changed, 21 insertions, 0 deletions
diff --git a/typing/typecore.ml b/typing/typecore.ml
index 1ddd3fe1eb..9cd90ea202 100644
--- a/typing/typecore.ml
+++ b/typing/typecore.ml
@@ -690,8 +690,29 @@ let rec is_nonexpansive exp =
Vars.fold (fun _ (mut,_,_) b -> decr count; b && mut = Immutable)
vars true &&
!count = 0
+ | Texp_pack mexp ->
+ is_nonexpansive_mod mexp
| _ -> false
+and is_nonexpansive_mod mexp =
+ match mexp.mod_desc with
+ | Tmod_ident _ -> true
+ | Tmod_functor _ -> true
+ | Tmod_unpack (e, _) -> is_nonexpansive e
+ | Tmod_constraint (m, _, _) -> is_nonexpansive_mod m
+ | Tmod_structure items ->
+ List.for_all
+ (function
+ | Tstr_eval _ | Tstr_primitive _ | Tstr_type _ | Tstr_modtype _ | Tstr_open _ | Tstr_cltype _ | Tstr_exn_rebind _ -> true
+ | Tstr_value (_, pat_exp_list) -> List.for_all (fun (_, exp) -> is_nonexpansive exp) pat_exp_list
+ | Tstr_module (_, m) | Tstr_include (m, _) -> is_nonexpansive_mod m
+ | Tstr_recmodule id_mod_list -> List.for_all (fun (_, m) -> is_nonexpansive_mod m) id_mod_list
+ | Tstr_exception _ -> false (* safe to return true? *)
+ | Tstr_class _ -> false (* could be more precise *)
+ )
+ items
+ | Tmod_apply _ -> false
+
and is_nonexpansive_opt = function
None -> true
| Some e -> is_nonexpansive e