Skip to content

Commit 83762af

Browse files
committed
Merge pull request ocaml#11622 from Octachron/fix_recursive_types_in_constructor_mismatch
Printtyp: avoid stack overflow when printing constructors or records with recursive types in inclusion error messages (cherry picked from commit 74e6ee2)
1 parent ca48730 commit 83762af

File tree

3 files changed

+102
-0
lines changed

3 files changed

+102
-0
lines changed

Changes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ OCaml 4.14 maintenance branch
5555
(Ulysse Gérard and Florian Angeletti, review Florian Angeletti and
5656
Gabriel Scherer)
5757

58+
- #11622: Prevent stack overflow when printing a constructor or record
59+
mismatch error involving recursive types.
60+
(Florian Angeletti, review by Gabriel Scherer)
61+
5862
OCaml 4.14.0 (28 March 2022)
5963
----------------------------
6064

testsuite/tests/typing-modules/inclusion_errors.ml

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,3 +1715,96 @@ Error: Signature mismatch:
17151715
type t = < m : int >
17161716
A private row type would be revealed.
17171717
|}];;
1718+
1719+
1720+
(** Unexpected recursive types *)
1721+
module M: sig
1722+
type _ t = A : (<x:'a> as 'a) -> (<y:'b> as 'b) t
1723+
end = struct
1724+
type _ t = A : (<x:'a * 'a> as 'a) -> (<y:'b> as 'b) t
1725+
end
1726+
[%%expect {|
1727+
Lines 3-5, characters 6-3:
1728+
3 | ......struct
1729+
4 | type _ t = A : (<x:'a * 'a> as 'a) -> (<y:'b> as 'b) t
1730+
5 | end
1731+
Error: Signature mismatch:
1732+
Modules do not match:
1733+
sig
1734+
type _ t = A : (< x : 'b * 'b > as 'b) -> (< y : 'a > as 'a) t
1735+
end
1736+
is not included in
1737+
sig type _ t = A : (< x : 'b > as 'b) -> (< y : 'a > as 'a) t end
1738+
Type declarations do not match:
1739+
type _ t = A : (< x : 'b * 'b > as 'b) -> (< y : 'a > as 'a) t
1740+
is not included in
1741+
type _ t = A : (< x : 'b > as 'b) -> (< y : 'a > as 'a) t
1742+
Constructors do not match:
1743+
A : (< x : 'b * 'b > as 'b) -> (< y : 'a > as 'a) t
1744+
is not the same as:
1745+
A : (< x : 'b > as 'b) -> (< y : 'a > as 'a) t
1746+
The type < x : 'a * 'a > as 'a is not equal to the type
1747+
< x : 'b > as 'b
1748+
Types for method x are incompatible
1749+
|}]
1750+
module R: sig
1751+
type t = { a: (<x:'a> as 'a) }
1752+
end = struct
1753+
type t = { a: (<x:'a * 'a> as 'a) }
1754+
end
1755+
[%%expect {|
1756+
Lines 3-5, characters 6-3:
1757+
3 | ......struct
1758+
4 | type t = { a: (<x:'a * 'a> as 'a) }
1759+
5 | end
1760+
Error: Signature mismatch:
1761+
Modules do not match:
1762+
sig type t = { a : < x : 'a * 'a > as 'a; } end
1763+
is not included in
1764+
sig type t = { a : < x : 'a > as 'a; } end
1765+
Type declarations do not match:
1766+
type t = { a : < x : 'a * 'a > as 'a; }
1767+
is not included in
1768+
type t = { a : < x : 'a > as 'a; }
1769+
Fields do not match:
1770+
a : < x : 'a * 'a > as 'a;
1771+
is not the same as:
1772+
a : < x : 'a > as 'a;
1773+
The type < x : 'a * 'a > as 'a is not equal to the type
1774+
< x : 'b > as 'b
1775+
Types for method x are incompatible
1776+
|}]
1777+
type _ ext = ..
1778+
module Ext: sig
1779+
type _ ext += A : (<x:'a> as 'a) -> (<y:'b> as 'b) ext
1780+
end = struct
1781+
type _ ext += A : (<x:'a * 'a> as 'a) -> (<y:'b> as 'b) ext
1782+
end
1783+
[%%expect {|
1784+
type _ ext = ..
1785+
Lines 4-6, characters 6-3:
1786+
4 | ......struct
1787+
5 | type _ ext += A : (<x:'a * 'a> as 'a) -> (<y:'b> as 'b) ext
1788+
6 | end
1789+
Error: Signature mismatch:
1790+
Modules do not match:
1791+
sig
1792+
type _ ext +=
1793+
A : (< x : 'b * 'b > as 'b) -> (< y : 'a > as 'a) ext
1794+
end
1795+
is not included in
1796+
sig
1797+
type _ ext += A : (< x : 'b > as 'b) -> (< y : 'a > as 'a) ext
1798+
end
1799+
Extension declarations do not match:
1800+
type _ ext += A : (< x : 'b * 'b > as 'b) -> (< y : 'a > as 'a) ext
1801+
is not included in
1802+
type _ ext += A : (< x : 'b > as 'b) -> (< y : 'a > as 'a) ext
1803+
Constructors do not match:
1804+
A : (< x : 'b * 'b > as 'b) -> (< y : 'a > as 'a) ext
1805+
is not the same as:
1806+
A : (< x : 'b > as 'b) -> (< y : 'a > as 'a) ext
1807+
The type < x : 'a * 'a > as 'a is not equal to the type
1808+
< x : 'b > as 'b
1809+
Types for method x are incompatible
1810+
|}]

typing/printtyp.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,10 +1466,13 @@ and tree_of_label l =
14661466

14671467
let constructor ppf c =
14681468
reset_except_context ();
1469+
prepare_type_constructor_arguments c.cd_args;
1470+
Option.iter prepare_type c.cd_res;
14691471
!Oprint.out_constr ppf (tree_of_constructor c)
14701472

14711473
let label ppf l =
14721474
reset_except_context ();
1475+
prepare_type l.ld_type;
14731476
!Oprint.out_label ppf (tree_of_label l)
14741477

14751478
let tree_of_type_declaration id decl rs =
@@ -1537,6 +1540,8 @@ let extension_constructor id ppf ext =
15371540

15381541
let extension_only_constructor id ppf ext =
15391542
reset_except_context ();
1543+
prepare_type_constructor_arguments ext.ext_args;
1544+
Option.iter prepare_type ext.ext_ret_type;
15401545
let name = Ident.name id in
15411546
let args, ret =
15421547
extension_constructor_args_and_ret_type_subtree

0 commit comments

Comments
 (0)