Skip to content

Commit 4194036

Browse files
flambda-backend: Non_null_value layout (#2480)
Implement the `non_null_value` layout, which is a sublayout of `value`. --------- Co-authored-by: Diana Kalinichenko <[email protected]>
1 parent 5f6b7fe commit 4194036

17 files changed

+421
-14
lines changed

lambda/matching.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ let jkind_layout_must_be_value loc jkind =
118118
outlived its usefulness and should be deleted. *)
119119
let check_record_field_jkind lbl =
120120
match Jkind.(get_default_value lbl.lbl_jkind), lbl.lbl_repres with
121-
| (Value | Immediate | Immediate64), _ -> ()
121+
| (Value | Immediate | Immediate64 | Non_null_value), _ -> ()
122122
| Float64, (Record_ufloat | Record_mixed _) -> ()
123123
| Float64, (Record_boxed _ | Record_inlined _
124124
| Record_unboxed | Record_float) ->
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
(* TEST
2+
flags = "-extension layouts_alpha";
3+
expect;
4+
*)
5+
type t_non_null_value : non_null_value
6+
7+
[%%expect{|
8+
type t_non_null_value : non_null_value
9+
|}]
10+
11+
(* [non_null_value] can be used in regular functions and modules: *)
12+
13+
let non_null_id (x : t_non_null_value) = x
14+
15+
module type S1 = sig
16+
val x : t_non_null_value
17+
val f : t_non_null_value -> t_non_null_value option
18+
end;;
19+
20+
[%%expect{|
21+
val non_null_id : t_non_null_value -> t_non_null_value = <fun>
22+
module type S1 =
23+
sig
24+
val x : t_non_null_value
25+
val f : t_non_null_value -> t_non_null_value option
26+
end
27+
|}]
28+
29+
30+
(* [non_null_value] is a sublayout of [value]: *)
31+
32+
let id_value : ('a : value). 'a -> 'a = fun x -> x
33+
34+
let id_non_null_value : ('a : non_null_value). 'a -> 'a = fun x -> id_value x
35+
36+
module type S2 = sig
37+
type t : value
38+
val f : t -> t
39+
end
40+
41+
module F (X : sig type t : non_null_value val f : t -> t end) : S2 = X;;
42+
43+
[%%expect{|
44+
val id_value : 'a -> 'a = <fun>
45+
val id_non_null_value : ('a : non_null_value). 'a -> 'a = <fun>
46+
module type S2 = sig type t : value val f : t -> t end
47+
module F : functor (X : sig type t : non_null_value val f : t -> t end) -> S2
48+
|}]
49+
50+
(* [value] is not a sublayout of [non_null_value]: *)
51+
52+
let id_value' : ('a : value). 'a -> 'a = fun x -> id_non_null_value x;;
53+
54+
[%%expect{|
55+
Line 1, characters 41-69:
56+
1 | let id_value' : ('a : value). 'a -> 'a = fun x -> id_non_null_value x;;
57+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
58+
Error: This definition has type 'b -> 'b which is less general than
59+
'a. 'a -> 'a
60+
The layout of 'a is value, because
61+
of the annotation on the universal variable 'a.
62+
But the layout of 'a must be a sublayout of non_null_value, because
63+
of the definition of id_non_null_value at line 3, characters 4-21.
64+
|}]
65+
66+
module type S3 = sig
67+
type t : non_null_value
68+
val f : t -> t
69+
end
70+
71+
module F (X : sig type t : value val f : t -> t end) : S3 = X;;
72+
73+
[%%expect{|
74+
module type S3 = sig type t : non_null_value val f : t -> t end
75+
Line 6, characters 60-61:
76+
6 | module F (X : sig type t : value val f : t -> t end) : S3 = X;;
77+
^
78+
Error: Signature mismatch:
79+
Modules do not match:
80+
sig type t = X.t val f : t -> t end
81+
is not included in
82+
S3
83+
Type declarations do not match:
84+
type t = X.t
85+
is not included in
86+
type t : non_null_value
87+
The layout of the first is value, because
88+
of the definition of t at line 6, characters 18-32.
89+
But the layout of the first must be a sublayout of non_null_value, because
90+
of the definition of t at line 2, characters 2-25.
91+
|}]
92+
93+
(* Something else like [float64] is also not a sublayout of [non_null_value]: *)
94+
95+
let id_float_64 : ('a : float64). 'a -> 'a = fun x -> id_non_null_value x;;
96+
97+
[%%expect{|
98+
Line 1, characters 72-73:
99+
1 | let id_float_64 : ('a : float64). 'a -> 'a = fun x -> id_non_null_value x;;
100+
^
101+
Error: This expression has type ('a : float64)
102+
but an expression was expected of type ('b : non_null_value)
103+
The layout of 'a is non_null_value, because
104+
of the definition of id_non_null_value at line 3, characters 4-21.
105+
But the layout of 'a must overlap with float64, because
106+
of the annotation on the universal variable 'a.
107+
|}]
108+
109+
module type S4 = sig
110+
type t : non_null_value
111+
val f : t -> t
112+
end
113+
114+
module F (X : sig type t : float64 val f : t -> t end) : S4 = X;;
115+
116+
[%%expect{|
117+
module type S4 = sig type t : non_null_value val f : t -> t end
118+
Line 6, characters 62-63:
119+
6 | module F (X : sig type t : float64 val f : t -> t end) : S4 = X;;
120+
^
121+
Error: Signature mismatch:
122+
Modules do not match:
123+
sig type t = X.t val f : t -> t end
124+
is not included in
125+
S4
126+
Type declarations do not match:
127+
type t = X.t
128+
is not included in
129+
type t : non_null_value
130+
The layout of the first is float64, because
131+
of the definition of t at line 6, characters 18-34.
132+
But the layout of the first must be a sublayout of non_null_value, because
133+
of the definition of t at line 2, characters 2-25.
134+
|}]

testsuite/tests/typing-layouts/annots.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ Error: Layout void is more experimental than allowed by the enabled layouts exte
3131
You must enable -extension layouts_alpha to use this feature.
3232
|}]
3333

34+
type t_non_null_value : non_null_value;;
35+
36+
[%%expect{|
37+
Line 1, characters 24-38:
38+
1 | type t_non_null_value : non_null_value;;
39+
^^^^^^^^^^^^^^
40+
Error: Layout non_null_value is more experimental than allowed by the enabled layouts extension.
41+
You must enable -extension layouts_alpha to use this feature.
42+
|}]
43+
3444
(***************************************)
3545
(* Test 1: annotation on type variable *)
3646

testsuite/tests/typing-layouts/basics.ml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ Error: Layout void is more experimental than allowed by the enabled layouts exte
3131
You must enable -extension layouts_alpha to use this feature.
3232
|}];;
3333

34+
type t_non_null_value : non_null_value;;
35+
[%%expect{|
36+
Line 1, characters 24-38:
37+
1 | type t_non_null_value : non_null_value;;
38+
^^^^^^^^^^^^^^
39+
Error: Layout non_null_value is more experimental than allowed by the enabled layouts extension.
40+
You must enable -extension layouts_alpha to use this feature.
41+
|}]
42+
3443
(******************************************************************)
3544
(* Test 1: Allow non-representable function args/returns in types *)
3645

0 commit comments

Comments
 (0)