Skip to content

Commit cf303fc

Browse files
author
Jacques Garrigue
committed
Fix PR#6992
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@16427 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
1 parent f5bf4bd commit cf303fc

File tree

2 files changed

+31
-24
lines changed

2 files changed

+31
-24
lines changed

Changes

+1
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ Bug fixes:
178178
- PR#6982: unexpected type error when packing a module alias
179179
- PR#6985: `module type of struct include Bar end exposes
180180
%s#row when Bar contains private row types
181+
- PR#6992: Segfault from bug in GADT/module typing
181182
- PR#6993: Segfault from recursive modules violating exhaustiveness assumptions
182183
- GPR#205: Clear caml_backtrace_last_exn before registering as root (report
183184
and fix by Frederic Bour)

typing/ctype.ml

+30-24
Original file line numberDiff line numberDiff line change
@@ -1594,11 +1594,12 @@ let generic_private_abbrev env path =
15941594
with Not_found -> false
15951595

15961596
let is_contractive env ty =
1597-
match (repr ty).desc with
1597+
try match (repr ty).desc with
15981598
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
16011601
| _ -> true
1602+
with Not_found -> false
16021603

16031604
(* Code moved to Typedecl
16041605
@@ -1657,11 +1658,11 @@ let allow_recursive env ty =
16571658

16581659
let rec occur_rec env visited ty0 ty =
16591660
if ty == ty0 then raise Occur;
1660-
let occur_ok = allow_recursive env ty in
1661+
if allow_recursive env ty then () else
16611662
match ty.desc with
16621663
Tconstr(p, tl, abbrev) ->
16631664
begin try
1664-
if occur_ok || List.memq ty visited then raise Occur;
1665+
if List.memq ty visited then raise Occur;
16651666
iter_type_expr (occur_rec env (ty::visited) ty0) ty
16661667
with Occur -> try
16671668
let ty' = try_expand_head try_expand_once env ty in
@@ -1672,16 +1673,15 @@ let rec occur_rec env visited ty0 ty =
16721673
match ty'.desc with
16731674
Tobject _ | Tvariant _ -> ()
16741675
| _ ->
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'
16771678
with Cannot_expand ->
1678-
if not occur_ok then raise Occur
1679+
raise Occur
16791680
end
16801681
| Tobject _ | Tvariant _ ->
16811682
()
16821683
| _ ->
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
16851685

16861686
let type_changed = ref false (* trace possible changes to the studied type *)
16871687

@@ -1702,24 +1702,30 @@ let occur_in env ty0 t =
17021702

17031703
(* Check that a local constraint is well-founded *)
17041704
(* 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 *)
17061707
let rec local_non_recursive_abbrev visited env p ty =
17071708
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
17101710
match ty.desc with
17111711
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
17131715
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
17161722
end
17171723
| _ -> ()
17181724
end
17191725

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+
17231729

17241730
(*****************************)
17251731
(* Polymorphic Unification *)
@@ -2222,6 +2228,7 @@ let find_newtype_level env path =
22222228
with Not_found -> assert false
22232229

22242230
let add_gadt_equation env source destination =
2231+
local_non_recursive_abbrev !env (Path.Pident source) destination;
22252232
let destination = duplicate_type destination in
22262233
let source_lev = find_newtype_level !env (Path.Pident source) in
22272234
let decl = new_declaration (Some source_lev) (Some destination) in
@@ -2480,20 +2487,19 @@ and unify3 env t1 t1' t2 t2' =
24802487
Tconstr ((Path.Pident p') as path',[],_))
24812488
when is_newtype !env path && is_newtype !env path'
24822489
&& !generate_equations ->
2483-
let source,destination =
2490+
let source, destination =
24842491
if find_newtype_level !env path > find_newtype_level !env path'
24852492
then p,t2'
24862493
else p',t1'
2487-
in add_gadt_equation env source destination
2494+
in
2495+
add_gadt_equation env source destination
24882496
| (Tconstr ((Path.Pident p) as path,[],_), _)
24892497
when is_newtype !env path && !generate_equations ->
24902498
reify env t2';
2491-
(* local_non_recursive_abbrev !env (Path.Pident p) t2'; *)
24922499
add_gadt_equation env p t2'
24932500
| (_, Tconstr ((Path.Pident p) as path,[],_))
24942501
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';
24972503
add_gadt_equation env p t1'
24982504
| (Tconstr (_,_,_), _) | (_, Tconstr (_,_,_)) when !umode = Pattern ->
24992505
reify env t1';

0 commit comments

Comments
 (0)