Skip to content

Commit

Permalink
typing: fix a try_expand_once forgotten from ocaml#10170
Browse files Browse the repository at this point in the history
On OCaml versions 5.1 and older, this caused a Ctype.Escape(_)
uncaught exception on the included test case.

Reported-by: Neven Villani <vanille@crans.org>
  • Loading branch information
gasche committed Feb 14, 2024
1 parent ef62c57 commit 09b27f3
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
Expand Up @@ -2429,6 +2429,10 @@ OCaml 4.14 maintenance version
- #12878: fix incorrect treatment of injectivity for private recursive types.
(Jeremy Yallop, review by Gabriel Scherer and Jacques Garrigue)

- #12971, #12974: fix an uncaught Ctype.Escape exception on some
invalid programs forming recursive types.
(Gabriel Scherer, review by Florian Angeletti, report by Neven Villani)

- #12264, #12289: Fix compact_allocate to avoid a pathological case
that causes very slow compaction.
(Damien Doligez, report by Arseniy Alekseyev, review by Sadiq Jaffer)
Expand Down
9 changes: 9 additions & 0 deletions testsuite/tests/typing-misc-bugs/pr12971.compilers.reference
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module Seq :
sig
type 'a t = unit -> 'a node
and 'a node
val empty : 'a t
val cons : 'a -> 'a t -> 'a t
end
type 'a t = T of 'a
val wrong_to_seq : ('a Seq.t as 'a) Seq.t t -> 'a Seq.t Seq.t
32 changes: 32 additions & 0 deletions testsuite/tests/typing-misc-bugs/pr12971.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
(* TEST_BELOW *)

module Seq : sig
type 'a t = unit -> 'a node
and 'a node

val empty : 'a t
val cons : 'a -> 'a t -> 'a t
end = struct
type 'a t = unit -> 'a node
and 'a node = unit

let empty () = ()
let cons x xs () = ()
end

type 'a t = T of 'a

(* Note: the current behavior of this function is believed to be
a bug, in the sense that it creates an equi-recursive type even in
absence of the -rectypes flag. On the other hand, it does not fail
with the Ctype.Escape exception, as it did from 4.13 to 5.1. *)
let wrong_to_seq (xt : 'a t) : 'a Seq.t =
let T x = xt in
Seq.cons Seq.empty x

(* TEST
ocamlc_flags = "-i";
setup-ocamlc.byte-build-env;
ocamlc.byte;
check-ocamlc.byte-output;
*)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
File "pr12971_bis.ml", line 17, characters 12-48:
17 | let strange x = Seq.[cons x empty; cons empty x]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: This expression has type "('a Seq.t as 'a) Seq.t -> 'a Seq.t Seq.t list"
but an expression was expected of type
"('a Seq.t as 'a) Seq.t -> 'a Seq.t Seq.t list"
25 changes: 25 additions & 0 deletions testsuite/tests/typing-misc-bugs/pr12971_bis.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
(* TEST_BELOW *)

module Seq : sig
type 'a t = unit -> 'a node
and 'a node

val empty : 'a t
val cons : 'a -> 'a t -> 'a t
end = struct
type 'a t = unit -> 'a node
and 'a node = unit

let empty () = ()
let cons x xs () = ()
end

let strange x = Seq.[cons x empty; cons empty x]

(* TEST
ocamlc_byte_exit_status = "2";
ocamlc_flags = "-i";
setup-ocamlc.byte-build-env;
ocamlc.byte;
check-ocamlc.byte-output;
*)
2 changes: 1 addition & 1 deletion typing/ctype.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1841,7 +1841,7 @@ let rec occur_rec env allow_recursive visited ty0 ty =
let visited = TypeSet.add ty visited in
iter_type_expr (occur_rec env allow_recursive visited ty0) ty
with Occur -> try
let ty' = try_expand_head try_expand_once env ty in
let ty' = try_expand_head try_expand_safe env ty in
(* This call used to be inlined, but there seems no reason for it.
Message was referring to change in rev. 1.58 of the CVS repo. *)
occur_rec env allow_recursive visited ty0 ty'
Expand Down

0 comments on commit 09b27f3

Please sign in to comment.