-
Notifications
You must be signed in to change notification settings - Fork 77
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
314 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
228 changes: 228 additions & 0 deletions
228
testsuite/tests/typing-layouts-unboxed-records/recursive.ml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,228 @@ | ||
(* TEST | ||
flambda2; | ||
include stdlib_upstream_compatible; | ||
flags = "-extension layouts_alpha"; | ||
{ | ||
expect; | ||
} | ||
*) | ||
|
||
(* CR layouts 7.2: figure out the story for recursive unboxed products. | ||
Consider that the following is allowed upstream: | ||
type t = { t : t } [@@unboxed] | ||
We should also give good errors for infinite-size unboxed records (see the test at the | ||
bottom of this file with a depth-100 kind). | ||
*) | ||
|
||
(************************************) | ||
(* Basic recursive unboxed products *) | ||
|
||
type t : value = #{ t : t } | ||
[%%expect{| | ||
type t = #{ t : t; } | ||
|}] | ||
|
||
type t : float64 = #{ t : t } | ||
[%%expect{| | ||
type t = #{ t : t; } | ||
|}] | ||
|
||
|
||
type t : value = #{ t : t } | ||
[%%expect{| | ||
type t = #{ t : t; } | ||
|}] | ||
|
||
type bad = #{ bad : bad ; i : int} | ||
[%%expect{| | ||
Line 1, characters 0-34: | ||
1 | type bad = #{ bad : bad ; i : int} | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
Error: | ||
The layout of bad is any & any | ||
because it is an unboxed record. | ||
But the layout of bad must be representable | ||
because it is the type of record field bad. | ||
|}] | ||
|
||
type bad = #{ bad : bad } | ||
[%%expect{| | ||
Line 1, characters 0-25: | ||
1 | type bad = #{ bad : bad } | ||
^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
Error: | ||
The layout of bad is any | ||
because a dummy kind of any is used to check mutually recursive datatypes. | ||
Please notify the Jane Street compilers group if you see this output. | ||
But the layout of bad must be representable | ||
because it is the type of record field bad. | ||
|}] | ||
|
||
type a_bad = #{ b_bad : b_bad } | ||
and b_bad = #{ a_bad : a_bad } | ||
[%%expect{| | ||
Line 1, characters 0-31: | ||
1 | type a_bad = #{ b_bad : b_bad } | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
Error: | ||
The layout of a_bad is any | ||
because a dummy kind of any is used to check mutually recursive datatypes. | ||
Please notify the Jane Street compilers group if you see this output. | ||
But the layout of a_bad must be representable | ||
because it is the type of record field a_bad. | ||
|}] | ||
|
||
type bad : any = #{ bad : bad } | ||
[%%expect{| | ||
Line 1, characters 0-31: | ||
1 | type bad : any = #{ bad : bad } | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
Error: | ||
The layout of bad is any | ||
because of the annotation on the declaration of the type bad. | ||
But the layout of bad must be representable | ||
because it is the type of record field bad. | ||
|}] | ||
|
||
type 'a id = #{ a : 'a } | ||
type bad = bad id | ||
[%%expect{| | ||
type 'a id = #{ a : 'a; } | ||
Line 2, characters 0-17: | ||
2 | type bad = bad id | ||
^^^^^^^^^^^^^^^^^ | ||
Error: The type abbreviation "bad" is cyclic: | ||
"bad" = "bad id", | ||
"bad id" contains "bad" | ||
|}] | ||
|
||
|
||
type 'a bad = #{ bad : 'a bad ; u : 'a} | ||
[%%expect{| | ||
Line 1, characters 0-39: | ||
1 | type 'a bad = #{ bad : 'a bad ; u : 'a} | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
Error: | ||
The layout of 'a bad is any & any | ||
because it is an unboxed record. | ||
But the layout of 'a bad must be representable | ||
because it is the type of record field bad. | ||
|}] | ||
|
||
type 'a bad = { bad : 'a bad ; u : 'a} | ||
[%%expect{| | ||
type 'a bad = { bad : 'a bad; u : 'a; } | ||
|}] | ||
|
||
|
||
(***************************************) | ||
(* Recursive unboxed records with void *) | ||
|
||
type t_void : void | ||
|
||
type ('a : void) t = #{ x : 'a ; y : t_void } | ||
[%%expect{| | ||
type t_void : void | ||
type ('a : void) t = #{ x : 'a; y : t_void; } | ||
|}] | ||
|
||
type t = { x : t_void } [@@unboxed] | ||
[%%expect{| | ||
type t = { x : t_void; } [@@unboxed] | ||
|}] | ||
|
||
type bad : void = #{ bad : bad } | ||
[%%expect{| | ||
type bad = #{ bad : bad; } | ||
|}] | ||
|
||
type ('a : void) bad = #{ bad : 'a bad ; u : 'a} | ||
[%%expect{| | ||
Line 1, characters 0-49: | ||
1 | type ('a : void) bad = #{ bad : 'a bad ; u : 'a} | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
Error: | ||
The layout of 'a bad is any & any | ||
because it is an unboxed record. | ||
But the layout of 'a bad must be representable | ||
because it is the type of record field bad. | ||
|}] | ||
|
||
|
||
(****************************) | ||
(* A particularly bad error *) | ||
|
||
type bad : float64 = #{ bad : bad ; i : int} | ||
[%%expect{| | ||
Line 1, characters 0-44: | ||
1 | type bad : float64 = #{ bad : bad ; i : int} | ||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
Error: The layout of type "bad" is (((((((((((((((((((((((((((((((((((( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
( | ||
(float64 & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value) & value | ||
because it is an unboxed record. | ||
But the layout of type "bad" must be a sublayout of float64 | ||
because of the annotation on the declaration of the type bad. | ||
|}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
(* TEST | ||
flambda2; | ||
include stdlib_upstream_compatible; | ||
flags = "-extension layouts_alpha -extension unique"; | ||
{ | ||
expect; | ||
} | ||
*) | ||
|
||
(* Uniqueness tests *) | ||
|
||
type t = #{ x : string ; y : string } | ||
let use_string (_s @ unique) = () | ||
let mk : unit -> t @ unique = fun () -> #{ x = "hi"; y = "hi" } | ||
[%%expect{| | ||
type t = #{ x : string; y : string; } | ||
val use_string : ('a : value_or_null). 'a @ unique -> unit = <fun> | ||
val mk : unit -> t @ unique = <fun> | ||
|}] | ||
|
||
(* Can access different fields *) | ||
let () = | ||
let t = mk () in | ||
use_string t.#x; | ||
use_string t.#y | ||
[%%expect{| | ||
|}] | ||
|
||
let () = | ||
let #{ x ; y } = mk () in | ||
use_string x; | ||
use_string y | ||
[%%expect{| | ||
|}] | ||
|
||
(* Cannot access the same field twice *) | ||
let () = | ||
let t = mk () in | ||
use_string t.#x; | ||
use_string t.#x | ||
[%%expect{| | ||
Line 4, characters 13-17: | ||
4 | use_string t.#x | ||
^^^^ | ||
Error: This value is used here, but it has already been used as unique: | ||
Line 3, characters 13-17: | ||
3 | use_string t.#x; | ||
^^^^ | ||
|
||
|}] | ||
|
||
let () = | ||
let #{ x ; y = _ } = mk () in | ||
use_string x; | ||
use_string x | ||
[%%expect{| | ||
Line 4, characters 13-14: | ||
4 | use_string x | ||
^ | ||
Error: This value is used here, but it has already been used as unique: | ||
Line 3, characters 13-14: | ||
3 | use_string x; | ||
^ | ||
|
||
|}] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters