summaryrefslogtreecommitdiff
path: root/typing/ctype.ml
diff options
context:
space:
mode:
Diffstat (limited to 'typing/ctype.ml')
-rw-r--r--typing/ctype.ml53
1 files changed, 34 insertions, 19 deletions
diff --git a/typing/ctype.ml b/typing/ctype.ml
index 21e6571d19..02b4ce2196 100644
--- a/typing/ctype.ml
+++ b/typing/ctype.ml
@@ -422,14 +422,15 @@ let closed_parameterized_type params ty =
let closed_type_decl decl =
try
List.iter mark_type decl.type_params;
- begin match decl.type_kind with
+ let rec closed_tkind = function
Type_abstract ->
()
| Type_variant v ->
List.iter (fun (_, tyl) -> List.iter closed_type tyl) v
| Type_record(r, rep) ->
List.iter (fun (_, _, ty) -> closed_type ty) r
- end;
+ | Type_private tkind -> closed_tkind tkind in
+ closed_tkind decl.type_kind;
begin match decl.type_manifest with
None -> ()
| Some ty -> closed_type ty
@@ -760,7 +761,7 @@ let rec copy ty =
let more = repr row.row_more in
(* We must substitute in a subtle way *)
begin match more.desc with
- Tsubst ({desc=Tvariant _} as ty2) ->
+ Tsubst ty2 when (repr ty2).desc <> Tunivar ->
(* This variant type has been already copied *)
ty.desc <- Tsubst ty2; (* avoid Tlink in the new type *)
Tlink ty2
@@ -928,7 +929,7 @@ let rec copy_sep fixed free bound visited ty =
let bound = tl @ bound in
let visited =
List.map2 (fun ty t -> ty,(t,bound)) tl tl' @ visited in
- Tpoly (copy_rec t1, tl')
+ Tpoly (copy_sep fixed free bound visited t1, tl')
| _ -> copy_type_desc copy_rec ty.desc
end;
t
@@ -1022,7 +1023,19 @@ let rec find_expans p1 =
| Mlink {contents = rem} ->
find_expans p1 rem
+
+(*
+ If the environnement has changed, memorized expansions might not
+ be correct anymore, and so we flush the cache. This is safe but
+ quite pessimistic: it would be enough to flush the cache when a
+ type or module definition is overriden in the environnement.
+*)
let previous_env = ref Env.empty
+let check_abbrev_env env =
+ if env != !previous_env then begin
+ cleanup_abbrev ();
+ previous_env := env
+ end
(* Expand an abbreviation. The expansion is memorized. *)
(*
@@ -1043,16 +1056,7 @@ let previous_env = ref Env.empty
and this other expansion fails.
*)
let expand_abbrev env ty =
- (*
- If the environnement has changed, memorized expansions might not
- be correct anymore, and so we flush the cache. This is safe but
- quite pessimistic: it would be enough to flush the cache when a
- type or module definition is overriden in the environnement.
- *)
- if env != !previous_env then begin
- cleanup_abbrev ();
- previous_env := env
- end;
+ check_abbrev_env env;
match ty with
{desc = Tconstr (path, args, abbrev); level = level} ->
let lookup_abbrev = proper_abbrevs path args abbrev in
@@ -1173,6 +1177,7 @@ let rec non_recursive_abbrev env ty0 ty =
end
let correct_abbrev env ident params ty =
+ check_abbrev_env env;
let ty0 = newgenvar () in
visited := [];
let abbrev = Mcons (Path.Pident ident, ty0, ty0, Mnil) in
@@ -2342,6 +2347,11 @@ let moregeneral env inst_nongen pat_sch subj_sch =
(* Equivalence between parameterized types *)
(*********************************************)
+let normalize_subst subst =
+ if List.exists
+ (function {desc=Tlink _}, _ | _, {desc=Tlink _} -> true | _ -> false)
+ !subst
+ then subst := List.map (fun (t1,t2) -> repr t1, repr t2) !subst
let rec eqtype rename type_pairs subst env t1 t2 =
if t1 == t2 then () else
@@ -2353,6 +2363,7 @@ let rec eqtype rename type_pairs subst env t1 t2 =
match (t1.desc, t2.desc) with
(Tvar, Tvar) when rename ->
begin try
+ normalize_subst subst;
if List.assq t1 !subst != t2 then raise (Unify [])
with Not_found ->
subst := (t1, t2) :: !subst
@@ -2372,6 +2383,7 @@ let rec eqtype rename type_pairs subst env t1 t2 =
match (t1'.desc, t2'.desc) with
(Tvar, Tvar) when rename ->
begin try
+ normalize_subst subst;
if List.assq t1' !subst != t2' then raise (Unify [])
with Not_found ->
subst := (t1', t2') :: !subst
@@ -2808,7 +2820,7 @@ let rec build_subtype env visited loops posi level t =
try
let t' = List.assq t loops in
warn := true;
- (List.assq t loops, Equiv)
+ (t', Equiv)
with Not_found ->
(t, Unchanged)
else
@@ -2852,7 +2864,7 @@ let rec build_subtype env visited loops posi level t =
end
| None -> assert false in
let ty =
- subst env t'.level abbrev None cl_abbr.type_params tl body in
+ subst env !current_level abbrev None cl_abbr.type_params tl body in
let ty = repr ty in
let ty1, tl1 =
match ty.desc with
@@ -3354,7 +3366,7 @@ let nondep_type_decl env mid id is_covariant decl =
type_arity = decl.type_arity;
type_kind =
begin try
- match decl.type_kind with
+ let rec kind_of_tkind = function
Type_abstract ->
Type_abstract
| Type_variant cstrs ->
@@ -3367,6 +3379,8 @@ let nondep_type_decl env mid id is_covariant decl =
(fun (c, mut, t) -> (c, mut, nondep_type_rec env mid t))
lbls,
rep)
+ | Type_private tkind -> Type_private (kind_of_tkind tkind) in
+ kind_of_tkind decl.type_kind
with Not_found when is_covariant ->
Type_abstract
end;
@@ -3384,13 +3398,14 @@ let nondep_type_decl env mid id is_covariant decl =
in
cleanup_types ();
List.iter unmark_type decl.type_params;
- begin match decl.type_kind with
+ let rec unmark_tkind = function
Type_abstract -> ()
| Type_variant cstrs ->
List.iter (fun (c, tl) -> List.iter unmark_type tl) cstrs
| Type_record(lbls, rep) ->
List.iter (fun (c, mut, t) -> unmark_type t) lbls
- end;
+ | Type_private tkind -> unmark_tkind tkind in
+ unmark_tkind decl.type_kind;
begin match decl.type_manifest with
None -> ()
| Some ty -> unmark_type ty