@@ -1594,11 +1594,12 @@ let generic_private_abbrev env path =
1594
1594
with Not_found -> false
1595
1595
1596
1596
let is_contractive env ty =
1597
- match (repr ty).desc with
1597
+ try match (repr ty).desc with
1598
1598
Tconstr (p , _ , _ ) ->
1599
- in_pervasives p ||
1600
- ( try is_datatype ( Env. find_type p env) with Not_found -> false )
1599
+ let decl = Env. find_type p env in
1600
+ in_pervasives p && decl.type_manifest = None || is_datatype decl
1601
1601
| _ -> true
1602
+ with Not_found -> false
1602
1603
1603
1604
(* Code moved to Typedecl
1604
1605
@@ -1657,11 +1658,11 @@ let allow_recursive env ty =
1657
1658
1658
1659
let rec occur_rec env visited ty0 ty =
1659
1660
if ty == ty0 then raise Occur ;
1660
- let occur_ok = allow_recursive env ty in
1661
+ if allow_recursive env ty then () else
1661
1662
match ty.desc with
1662
1663
Tconstr (p , tl , abbrev ) ->
1663
1664
begin try
1664
- if occur_ok || List. memq ty visited then raise Occur ;
1665
+ if List. memq ty visited then raise Occur ;
1665
1666
iter_type_expr (occur_rec env (ty::visited) ty0) ty
1666
1667
with Occur -> try
1667
1668
let ty' = try_expand_head try_expand_once env ty in
@@ -1672,16 +1673,15 @@ let rec occur_rec env visited ty0 ty =
1672
1673
match ty'.desc with
1673
1674
Tobject _ | Tvariant _ -> ()
1674
1675
| _ ->
1675
- if not ( allow_recursive env ty') then
1676
- iter_type_expr (occur_rec env (ty'::visited) ty0) ty'
1676
+ if allow_recursive env ty' then () else
1677
+ iter_type_expr (occur_rec env (ty'::visited) ty0) ty'
1677
1678
with Cannot_expand ->
1678
- if not occur_ok then raise Occur
1679
+ raise Occur
1679
1680
end
1680
1681
| Tobject _ | Tvariant _ ->
1681
1682
()
1682
1683
| _ ->
1683
- if not occur_ok then
1684
- iter_type_expr (occur_rec env visited ty0) ty
1684
+ iter_type_expr (occur_rec env visited ty0) ty
1685
1685
1686
1686
let type_changed = ref false (* trace possible changes to the studied type *)
1687
1687
@@ -1702,24 +1702,30 @@ let occur_in env ty0 t =
1702
1702
1703
1703
(* Check that a local constraint is well-founded *)
1704
1704
(* PR#6405: not needed since we allow recursion and work on normalized types *)
1705
- (*
1705
+ (* PR#6992: we actually need it for contractiveness *)
1706
+ (* This is a simplified version of occur, only for the rectypes case *)
1706
1707
let rec local_non_recursive_abbrev visited env p ty =
1707
1708
let ty = repr ty in
1708
- if not (List.memq ty !visited) then begin
1709
- visited := ty :: !visited;
1709
+ if not (List. memq ty visited) then begin
1710
1710
match ty.desc with
1711
1711
Tconstr (p' , args , abbrev ) ->
1712
- if Path.same p p' then raise Recursive_abbrev;
1712
+ if Path. same p p' then raise Occur ;
1713
+ if is_contractive env ty then () else
1714
+ let visited = ty :: visited in
1713
1715
begin try
1714
- local_non_recursive_abbrev visited env p (try_expand_once_opt env ty)
1715
- with Cannot_expand -> ()
1716
+ List. iter (local_non_recursive_abbrev visited env p) args
1717
+ with Occur -> try
1718
+ local_non_recursive_abbrev visited env p
1719
+ (try_expand_head try_expand_once env ty)
1720
+ with Cannot_expand ->
1721
+ raise Occur
1716
1722
end
1717
1723
| _ -> ()
1718
1724
end
1719
1725
1720
- let local_non_recursive_abbrev env p =
1721
- local_non_recursive_abbrev (ref []) env p
1722
- *)
1726
+ let local_non_recursive_abbrev env p ty =
1727
+ try local_non_recursive_abbrev [] env p ty with Occur -> raise ( Unify [] )
1728
+
1723
1729
1724
1730
(* ****************************)
1725
1731
(* Polymorphic Unification *)
@@ -2222,6 +2228,7 @@ let find_newtype_level env path =
2222
2228
with Not_found -> assert false
2223
2229
2224
2230
let add_gadt_equation env source destination =
2231
+ local_non_recursive_abbrev ! env (Path. Pident source) destination;
2225
2232
let destination = duplicate_type destination in
2226
2233
let source_lev = find_newtype_level ! env (Path. Pident source) in
2227
2234
let decl = new_declaration (Some source_lev) (Some destination) in
@@ -2480,20 +2487,19 @@ and unify3 env t1 t1' t2 t2' =
2480
2487
Tconstr ((Path. Pident p') as path',[] ,_))
2481
2488
when is_newtype ! env path && is_newtype ! env path'
2482
2489
&& ! generate_equations ->
2483
- let source,destination =
2490
+ let source, destination =
2484
2491
if find_newtype_level ! env path > find_newtype_level ! env path'
2485
2492
then p,t2'
2486
2493
else p',t1'
2487
- in add_gadt_equation env source destination
2494
+ in
2495
+ add_gadt_equation env source destination
2488
2496
| (Tconstr ((Path. Pident p) as path,[] ,_), _)
2489
2497
when is_newtype ! env path && ! generate_equations ->
2490
2498
reify env t2';
2491
- (* local_non_recursive_abbrev !env (Path.Pident p) t2'; *)
2492
2499
add_gadt_equation env p t2'
2493
2500
| (_, Tconstr ((Path. Pident p) as path,[] ,_))
2494
2501
when is_newtype ! env path && ! generate_equations ->
2495
- reify env t1' ;
2496
- (* local_non_recursive_abbrev !env (Path.Pident p) t1'; *)
2502
+ reify env t1';
2497
2503
add_gadt_equation env p t1'
2498
2504
| (Tconstr (_ ,_ ,_ ), _ ) | (_ , Tconstr (_ ,_ ,_ )) when ! umode = Pattern ->
2499
2505
reify env t1';
0 commit comments