summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--typing/ctype.ml20
-rw-r--r--typing/ctype.mli2
-rw-r--r--typing/parmatch.ml2
-rw-r--r--typing/typeclass.ml5
-rw-r--r--typing/typedecl.ml19
-rw-r--r--typing/typetexp.ml2
6 files changed, 31 insertions, 19 deletions
diff --git a/typing/ctype.ml b/typing/ctype.ml
index 51801debd..8c0e13f51 100644
--- a/typing/ctype.ml
+++ b/typing/ctype.ml
@@ -864,12 +864,7 @@ let expand_abbrev env ty =
try Env.find_type_expansion path env with Not_found ->
raise Cannot_expand
in
-(* begin try *)
subst env level abbrev (Some ty) params args body
-(* with Unify _ ->
- raise Cannot_expand
- end
-*)
end
| _ ->
assert false
@@ -895,6 +890,17 @@ let _ = try_expand_head' := try_expand_head
let rec expand_head env ty =
try try_expand_head env ty with Cannot_expand -> repr ty
+(* Make sure that the type parameters of the type constructor [ty]
+ respect the type constraints *)
+let enforce_constraints env ty =
+ match ty with
+ {desc = Tconstr (path, args, abbrev); level = level} ->
+ let decl = Env.find_type path env in
+ ignore
+ (subst env level (ref Mnil) None decl.type_params args (newvar2 level))
+ | _ ->
+ assert false
+
(* Recursively expand the head of a type.
Also expand #-types. *)
let rec full_expand env ty =
@@ -965,8 +971,8 @@ let rec occur_rec env visited ty0 ty =
iter_type_expr (occur_rec env (ty::visited) ty0) ty
with Occur -> try
let ty' = try_expand_head env ty in
- if List.memq ty' visited then raise Occur;
- occur_rec env (ty'::visited) ty0 ty'
+ if ty == ty0 || List.memq ty' visited then raise Occur;
+ iter_type_expr (occur_rec env (ty'::visited) ty0) ty'
with Cannot_expand ->
raise Occur
end
diff --git a/typing/ctype.mli b/typing/ctype.mli
index 52549d53c..cb4b8b648 100644
--- a/typing/ctype.mli
+++ b/typing/ctype.mli
@@ -106,6 +106,8 @@ val apply:
val expand_head: Env.t -> type_expr -> type_expr
val full_expand: Env.t -> type_expr -> type_expr
+val enforce_constraints: Env.t -> type_expr -> unit
+
val unify: Env.t -> type_expr -> type_expr -> unit
(* Unify the two types given. Raise [Unify] if not possible. *)
val filter_arrow: Env.t -> type_expr -> type_expr * type_expr
diff --git a/typing/parmatch.ml b/typing/parmatch.ml
index afd080d5e..bc6ce82ae 100644
--- a/typing/parmatch.ml
+++ b/typing/parmatch.ml
@@ -696,7 +696,7 @@ and pretty_lvals lbls ppf = function
fprintf ppf "%s=%a;@ %a" name pretty_val v (pretty_lvals lbls) rest
let top_pretty ppf v =
- fprintf ppf "@[%a@]@." pretty_val v
+ fprintf ppf "@[%a@]@?" pretty_val v
(******************************)
diff --git a/typing/typeclass.ml b/typing/typeclass.ml
index 33888a5e4..939abaa57 100644
--- a/typing/typeclass.ml
+++ b/typing/typeclass.ml
@@ -394,7 +394,10 @@ let rec class_field cl_num self_type meths vars
| Pcf_val (lab, mut, sexp, loc) ->
if StringSet.mem lab inh_vals then
Location.print_warning loc (Warnings.Hide_instance_variable lab);
- let exp = type_exp val_env sexp in
+ let exp =
+ try type_exp val_env sexp with Ctype.Unify [(ty, _)] ->
+ raise(Error(loc, Make_nongen_seltype ty))
+ in
let (id, val_env, met_env, par_env) =
enter_val cl_num vars lab mut exp.exp_type val_env met_env par_env
in
diff --git a/typing/typedecl.ml b/typing/typedecl.ml
index 6cf224fc0..2e4d25bfd 100644
--- a/typing/typedecl.ml
+++ b/typing/typedecl.ml
@@ -73,15 +73,6 @@ let transl_declaration env (name, sdecl) (id, decl) =
raise(Error(sdecl.ptype_loc, Repeated_parameter))
end;
- List.iter
- (function (sty, sty', loc) ->
- try
- Ctype.unify env (transl_simple_type env false sty)
- (transl_simple_type env false sty')
- with Ctype.Unify _ ->
- raise(Error(loc, Unconsistent_constraint)))
- sdecl.ptype_cstrs;
-
begin match sdecl.ptype_manifest with
None ->
()
@@ -95,6 +86,16 @@ let transl_declaration env (name, sdecl) (id, decl) =
raise(Error(sdecl.ptype_loc, Type_clash trace))
end
end;
+
+ List.iter
+ (function (sty, sty', loc) ->
+ try
+ Ctype.unify env (transl_simple_type env false sty)
+ (transl_simple_type env false sty')
+ with Ctype.Unify _ ->
+ raise(Error(loc, Unconsistent_constraint)))
+ sdecl.ptype_cstrs;
+
(id, decl)
(* Second pass: representation *)
diff --git a/typing/typetexp.ml b/typing/typetexp.ml
index f9ee2a86b..05f741d76 100644
--- a/typing/typetexp.ml
+++ b/typing/typetexp.ml
@@ -131,7 +131,7 @@ let rec transl_type env policy styp =
let params = List.map (fun _ -> Ctype.newvar ()) args in
let cstr = newty (Tconstr(path, params, ref Mnil)) in
begin try
- ignore(Ctype.expand_head env cstr)
+ Ctype.enforce_constraints env cstr
with Unify trace ->
raise (Error(styp.ptyp_loc, Type_mismatch trace))
end;