summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Garrigue <garrigue at math.nagoya-u.ac.jp>2003-11-19 12:38:44 +0000
committerJacques Garrigue <garrigue at math.nagoya-u.ac.jp>2003-11-19 12:38:44 +0000
commitde682fe5051c0f4539e4c6b292b71ec7043d9b02 (patch)
tree8d14003a1c275ec1a79c1cb3e752ac63b8f20052
parent372f16a6a118bd2ce88b432701f9a438b88442f9 (diff)
downloadocaml-de682fe5051c0f4539e4c6b292b71ec7043d9b02.tar.gz
fix unsoundness in is_nonexpansive
git-svn-id: http://caml.inria.fr/svn/ocaml/branches/fastclass@5933 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r--typing/typecore.ml13
1 files changed, 9 insertions, 4 deletions
diff --git a/typing/typecore.ml b/typing/typecore.ml
index 4d517ce976..47f87cf2c3 100644
--- a/typing/typecore.ml
+++ b/typing/typecore.ml
@@ -590,14 +590,19 @@ let rec is_nonexpansive exp =
| Texp_new (_, cl_decl) when Ctype.class_type_arity cl_decl.cty_type > 0 ->
true
(* Note: nonexpansive only means no _observable_ side effects *)
- | Texp_lazy e -> true
- | Texp_object ({cl_field=fields}, _, _) ->
+ | Texp_lazy e -> is_nonexpansive e
+ | Texp_object ({cl_field=fields}, {cty_vars=vars}, _) ->
+ let count = ref 0 in
List.for_all
(function
Cf_meth _ -> true
- | Cf_val (_,_,e) | Cf_init e -> is_nonexpansive e
+ | Cf_val (_,_,e) -> incr count; is_nonexpansive e
+ | Cf_init e -> is_nonexpansive e
| Cf_inher _ | Cf_let _ -> false)
- fields
+ fields &&
+ Vars.fold (fun _ (mut,_) b -> decr count; b && mut = Immutable)
+ vars true &&
+ !count = 0
| _ -> false
and is_nonexpansive_opt = function