Skip to content

Commit 8bc3fd7

Browse files
authored
flambda-backend: Allow more function argument / returns to be non-value (#1422)
* Polymorphic arguments might not be values * Copy tests to basics and basics_beta * Correct layout of optional arguments * Allow non-value layouts when inferring an app * Allow non-value arguments in approx_type * Allow exotic sorts in letop * Exotic layouts in andops * Comments from review * Foreshadow type_cases in comment
1 parent f2a5b93 commit 8bc3fd7

File tree

5 files changed

+303
-24
lines changed

5 files changed

+303
-24
lines changed

testsuite/tests/typing-layouts/basics.ml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,39 @@ Error: Layout void is used here, but the appropriate layouts extension is not en
251251
(* CR layouts v2: Once we allow non-value top-level module definitions, add
252252
tests showing that things get defaulted to value.
253253
*)
254+
255+
(********************************************************************)
256+
(* Test 23: checking the error message from impossible GADT matches *)
257+
258+
(* CR layouts: This test moved to [basics_alpha.ml] as it needs a non-value
259+
sort. Bring back here when we have one enabled by default. *)
260+
261+
(*****************************************************)
262+
(* Test 24: Polymorphic parameter with exotic layout *)
263+
264+
(* CR layouts: This test moved to [basics_alpha.ml] as it needs a non-value
265+
sort. Bring back here when we have one enabled by default. *)
266+
267+
(**************************************************)
268+
(* Test 25: Optional parameter with exotic layout *)
269+
270+
(* CR layouts: This test moved to [basics_alpha.ml] as it needs a non-value
271+
sort. Bring back here when we have one enabled by default. *)
272+
273+
(*********************************************************)
274+
(* Test 26: Inferring an application to an exotic layout *)
275+
276+
(* CR layouts: This test moved to [basics_alpha.ml] as it needs a non-value
277+
sort. Bring back here when we have one enabled by default. *)
278+
279+
(******************************************)
280+
(* Test 27: Exotic layouts in approx_type *)
281+
282+
(* CR layouts: This test moved to [basics_alpha.ml] as it needs a non-value
283+
sort. Bring back here when we have one enabled by default. *)
284+
285+
(************************************)
286+
(* Test 28: Exotic layouts in letop *)
287+
288+
(* CR layouts: This test moved to [basics_alpha.ml] as it needs a non-value
289+
sort. Bring back here when we have one enabled by default. *)

testsuite/tests/typing-layouts/basics_alpha.ml

Lines changed: 204 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -727,12 +727,12 @@ module M11_3 = struct
727727
let foo o (A x) = o # usevoid x
728728
end;;
729729
[%%expect{|
730-
Line 4, characters 32-33:
730+
Line 4, characters 12-33:
731731
4 | let foo o (A x) = o # usevoid x
732-
^
733-
Error: This expression has type ('a : void)
734-
but an expression was expected of type ('b : value)
735-
'a has layout value, which does not overlap with void.
732+
^^^^^^^^^^^^^^^^^^^^^
733+
Error: Non-value detected in [value_kind].
734+
Please report this error to the Jane Street compilers team.
735+
'a has layout void, which is not a sublayout of value.
736736
|}];;
737737

738738
module M11_4 = struct
@@ -1196,3 +1196,202 @@ Error: This pattern matches values of type (M.t_void, M.t_void) eq
11961196
(* CR layouts v2: error message is OK, but it could probably be better.
11971197
But a similar case without layouts is already pretty bad, so try
11981198
that before spending too much time here. *)
1199+
1200+
(*****************************************************)
1201+
(* Test 24: Polymorphic parameter with exotic layout *)
1202+
1203+
type 'a t2_void [@@void]
1204+
1205+
let f (x : 'a. 'a t2_void) = x
1206+
1207+
[%%expect{|
1208+
type 'a t2_void [@@void]
1209+
Line 3, characters 6-30:
1210+
3 | let f (x : 'a. 'a t2_void) = x
1211+
^^^^^^^^^^^^^^^^^^^^^^^^
1212+
Error: Non-value detected in [value_kind].
1213+
Please report this error to the Jane Street compilers team.
1214+
'a. 'a t2_void has layout void, which is not a sublayout of value.
1215+
|}]
1216+
1217+
(**************************************************)
1218+
(* Test 25: Optional parameter with exotic layout *)
1219+
1220+
let f (x : t_void) =
1221+
let g ?(x2 = x) () = () in
1222+
()
1223+
1224+
[%%expect{|
1225+
Line 2, characters 15-16:
1226+
2 | let g ?(x2 = x) () = () in
1227+
^
1228+
Error: This expression has type t_void but an expression was expected of type
1229+
('a : value)
1230+
t_void has layout void, which is not a sublayout of value.
1231+
|}]
1232+
1233+
(*********************************************************)
1234+
(* Test 26: Inferring an application to an exotic layout *)
1235+
1236+
let g f (x : t_void) : t_void = f x
1237+
1238+
[%%expect{|
1239+
Line 1, characters 8-35:
1240+
1 | let g f (x : t_void) : t_void = f x
1241+
^^^^^^^^^^^^^^^^^^^^^^^^^^^
1242+
Error: Non-value detected in [value_kind].
1243+
Please report this error to the Jane Street compilers team.
1244+
t_void has layout void, which is not a sublayout of value.
1245+
|}]
1246+
1247+
(******************************************)
1248+
(* Test 27: Exotic layouts in approx_type *)
1249+
1250+
let rec f : _ -> _ = fun (x : t_void) -> x
1251+
1252+
[%%expect{|
1253+
Line 1, characters 21-42:
1254+
1 | let rec f : _ -> _ = fun (x : t_void) -> x
1255+
^^^^^^^^^^^^^^^^^^^^^
1256+
Error: Non-value detected in [value_kind].
1257+
Please report this error to the Jane Street compilers team.
1258+
t_void has layout void, which is not a sublayout of value.
1259+
|}]
1260+
1261+
(**********************************************)
1262+
(* Test 28: Exotic layouts in letop and andop *)
1263+
1264+
(* CR layouts: this must be [let rec] and [and] so that we can test the
1265+
type-checker, as opposed to the value-kind check. After we have proper
1266+
support for a non-value argument type, remove the [rec], throughout
1267+
this test.
1268+
*)
1269+
let rec ( let* ) (x : t_void) f = ()
1270+
1271+
and q () =
1272+
let* x = assert false in
1273+
()
1274+
1275+
[%%expect{|
1276+
Line 1, characters 17-36:
1277+
1 | let rec ( let* ) (x : t_void) f = ()
1278+
^^^^^^^^^^^^^^^^^^^
1279+
Error: Non-value detected in [value_kind].
1280+
Please report this error to the Jane Street compilers team.
1281+
t_void has layout void, which is not a sublayout of value.
1282+
|}]
1283+
1284+
let rec ( let* ) x (f : t_void -> _) = ()
1285+
1286+
and q () =
1287+
let* x = assert false in
1288+
()
1289+
1290+
[%%expect{|
1291+
Lines 4-5, characters 2-4:
1292+
4 | ..let* x = assert false in
1293+
5 | ()
1294+
Error: Non-value detected in [value_kind].
1295+
Please report this error to the Jane Street compilers team.
1296+
t_void has layout void, which is not a sublayout of value.
1297+
|}]
1298+
1299+
let rec ( let* ) x (f : _ -> t_void) = ()
1300+
1301+
and q () =
1302+
let* x = assert false in
1303+
assert false
1304+
1305+
[%%expect{|
1306+
Line 5, characters 2-14:
1307+
5 | assert false
1308+
^^^^^^^^^^^^
1309+
Error: Non-value detected in [value_kind].
1310+
Please report this error to the Jane Street compilers team.
1311+
t_void has layout void, which is not a sublayout of value.
1312+
|}]
1313+
1314+
let rec ( let* ) x f : t_void = assert false
1315+
1316+
and q () =
1317+
let* x = 5 in
1318+
()
1319+
1320+
[%%expect{|
1321+
Line 1, characters 19-44:
1322+
1 | let rec ( let* ) x f : t_void = assert false
1323+
^^^^^^^^^^^^^^^^^^^^^^^^^
1324+
Error: Non-value detected in [value_kind].
1325+
Please report this error to the Jane Street compilers team.
1326+
t_void has layout void, which is not a sublayout of value.
1327+
|}]
1328+
1329+
let rec ( let* ) x f = ()
1330+
and ( and* ) x1 (x2 : t_void) = ()
1331+
and q () =
1332+
let* x = 5
1333+
and* y = assert false
1334+
in
1335+
()
1336+
1337+
[%%expect{|
1338+
Line 2, characters 16-34:
1339+
2 | and ( and* ) x1 (x2 : t_void) = ()
1340+
^^^^^^^^^^^^^^^^^^
1341+
Error: Non-value detected in [value_kind].
1342+
Please report this error to the Jane Street compilers team.
1343+
t_void has layout void, which is not a sublayout of value.
1344+
|}]
1345+
1346+
let rec ( let* ) x f = ()
1347+
and ( and* ) (x1 : t_void) x2 = ()
1348+
and q () =
1349+
let* x = assert false
1350+
and* y = 5
1351+
in
1352+
()
1353+
1354+
[%%expect{|
1355+
Line 2, characters 13-34:
1356+
2 | and ( and* ) (x1 : t_void) x2 = ()
1357+
^^^^^^^^^^^^^^^^^^^^^
1358+
Error: Non-value detected in [value_kind].
1359+
Please report this error to the Jane Street compilers team.
1360+
t_void has layout void, which is not a sublayout of value.
1361+
|}]
1362+
1363+
let rec ( let* ) x f = ()
1364+
and ( and* ) x1 x2 : t_void = assert false
1365+
and q () =
1366+
let* x = 5
1367+
and* y = 5
1368+
in
1369+
()
1370+
1371+
[%%expect{|
1372+
Line 1, characters 17-25:
1373+
1 | let rec ( let* ) x f = ()
1374+
^^^^^^^^
1375+
Error: Non-value detected in [value_kind].
1376+
Please report this error to the Jane Street compilers team.
1377+
t_void has layout void, which is not a sublayout of value.
1378+
|}]
1379+
1380+
(* CR layouts v5: when we allow non-values in tuples, this next one should
1381+
type-check *)
1382+
let rec ( let* ) x f = ()
1383+
and ( and* ) x1 x2 = assert false
1384+
and q () =
1385+
let* x : t_void = assert false
1386+
and* y = 5
1387+
in
1388+
()
1389+
1390+
[%%expect{|
1391+
Line 4, characters 9-19:
1392+
4 | let* x : t_void = assert false
1393+
^^^^^^^^^^
1394+
Error: This pattern matches values of type t_void
1395+
but a pattern was expected which matches values of type ('a : value)
1396+
t_void has layout void, which is not a sublayout of value.
1397+
|}]

testsuite/tests/typing-layouts/basics_beta.ml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,3 +457,39 @@ Line 1, characters 12-20:
457457
^^^^^^^^
458458
Error: Layout void is used here, but the appropriate layouts extension is not enabled
459459
|}];;
460+
461+
(********************************************************************)
462+
(* Test 23: checking the error message from impossible GADT matches *)
463+
464+
(* CR layouts v2: This test moved to [basics_alpha.ml] as it needs a non-value
465+
sort. Bring back here when we have one. *)
466+
467+
(*****************************************************)
468+
(* Test 24: Polymorphic parameter with exotic layout *)
469+
470+
(* CR layouts v2: This test moved to [basics_alpha.ml] as it needs a non-value
471+
sort. Bring back here when we have one. *)
472+
473+
(**************************************************)
474+
(* Test 25: Optional parameter with exotic layout *)
475+
476+
(* CR layouts v2: This test moved to [basics_alpha.ml] as it needs a non-value
477+
sort. Bring back here when we have one. *)
478+
479+
(*********************************************************)
480+
(* Test 26: Inferring an application to an exotic layout *)
481+
482+
(* CR layouts v2: This test moved to [basics_alpha.ml] as it needs a non-value
483+
sort. Bring back here when we have one. *)
484+
485+
(******************************************)
486+
(* Test 27: Exotic layouts in approx_type *)
487+
488+
(* CR layouts v2: This test moved to [basics_alpha.ml] as it needs a non-value
489+
sort. Bring back here when we have one. *)
490+
491+
(************************************)
492+
(* Test 28: Exotic layouts in letop *)
493+
494+
(* CR layouts v2: This test moved to [basics_alpha.ml] as it needs a non-value
495+
sort. Bring back here when we have one. *)

typing/ctype.ml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3755,12 +3755,15 @@ let filter_arrow env t l ~force_tpoly =
37553755
let t1 =
37563756
if not force_tpoly then begin
37573757
assert (not (is_optional l));
3758-
newvar2 level Layout.value
3758+
newvar2 level l1
37593759
end else begin
37603760
let t1 =
37613761
if is_optional l then
37623762
newty2 ~level
3763-
(Tconstr(Predef.path_option,[newvar2 level l1], ref Mnil))
3763+
(* CR layouts v5: Change the Layout.value when option can
3764+
hold non-values. *)
3765+
(Tconstr(Predef.path_option,[newvar2 level Layout.value],
3766+
ref Mnil))
37643767
else
37653768
newvar2 level l1
37663769
in

typing/typecore.ml

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3040,10 +3040,9 @@ let collect_unknown_apply_args env funct ty_fun mode_fun rev_args sargs ret_tvar
30403040
let ty_fun = expand_head env ty_fun in
30413041
match get_desc ty_fun with
30423042
| Tvar _ ->
3043-
(* CR layouts v2: value requirement to be relaxed *)
3044-
let ty_arg_mono = newvar Layout.value in
3043+
let ty_arg_mono = newvar (Layout.of_new_sort_var ()) in
30453044
let ty_arg = newmono ty_arg_mono in
3046-
let ty_res = newvar Layout.value in
3045+
let ty_res = newvar (Layout.of_new_sort_var ()) in
30473046
if ret_tvar &&
30483047
not (is_prim ~name:"%identity" funct) &&
30493048
not (is_prim ~name:"%obj_magic" funct)
@@ -3482,9 +3481,10 @@ let rec approx_type env sty =
34823481
end
34833482
| Ptyp_arrow (p, arg_sty, sty) ->
34843483
let arg_mode = Typetexp.get_alloc_mode arg_sty in
3485-
let var = newvar Layout.value in
34863484
let arg =
3487-
if is_optional p then type_option var else var
3485+
if is_optional p
3486+
then type_option (newvar Layout.value)
3487+
else newvar (Layout.of_new_sort_var ())
34883488
in
34893489
let ret = approx_type env sty in
34903490
let marg = Alloc_mode.of_const arg_mode in
@@ -5414,18 +5414,24 @@ and type_expect_
54145414
let op_path, op_desc = type_binding_op_ident env slet.pbop_op in
54155415
let op_type = instance op_desc.val_type in
54165416
let spat_params, ty_params =
5417-
(* CR layouts v5: eliminate value requirement *)
5418-
loop slet.pbop_pat (newvar Layout.value) sands
5419-
in
5420-
(* CR layouts v2: eliminate value requirement *)
5421-
let ty_func_result = newvar Layout.value in
5417+
(* The use of a sort var here instead of a value is a little suspect,
5418+
because this can be the component of a tuple if there are several
5419+
[and] operators. In practice, all will be OK, though, because this
5420+
type will get unified with a tuple type (in the [type_cases] below)
5421+
and the sort var will get set to [value]. However, we still use a
5422+
sort var here to allow for a non-[value] type when there are no
5423+
[and]s. *)
5424+
(* CR layouts v5: Remove above comment when we support tuples of
5425+
non-[value] types. *)
5426+
loop slet.pbop_pat (newvar (Layout.of_new_sort_var ())) sands
5427+
in
5428+
let ty_func_result = newvar (Layout.of_new_sort_var ()) in
54225429
let arrow_desc = Nolabel, Alloc_mode.global, Alloc_mode.global in
54235430
let ty_func =
54245431
newty (Tarrow(arrow_desc, newmono ty_params, ty_func_result, commu_ok))
54255432
in
5426-
(* CR layouts v2: eliminate value requirement *)
5427-
let ty_result = newvar Layout.value in
5428-
let ty_andops = newvar Layout.value in
5433+
let ty_result = newvar (Layout.of_new_sort_var ()) in
5434+
let ty_andops = newvar (Layout.of_new_sort_var ()) in
54295435
let ty_op =
54305436
newty (Tarrow(arrow_desc, newmono ty_andops,
54315437
newty (Tarrow(arrow_desc, newmono ty_func,
@@ -7155,10 +7161,9 @@ and type_andops env sarg sands expected_ty =
71557161
if !Clflags.principal then begin_def ();
71567162
let op_path, op_desc = type_binding_op_ident env sop in
71577163
let op_type = op_desc.val_type in
7158-
(* CR layouts v2: relax value requirements *)
7159-
let ty_arg = newvar Layout.value in
7160-
let ty_rest = newvar Layout.value in
7161-
let ty_result = newvar Layout.value in
7164+
let ty_arg = newvar (Layout.of_new_sort_var ()) in
7165+
let ty_rest = newvar (Layout.of_new_sort_var ()) in
7166+
let ty_result = newvar (Layout.of_new_sort_var ()) in
71627167
let arrow_desc = (Nolabel,Alloc_mode.global,Alloc_mode.global) in
71637168
let ty_rest_fun =
71647169
newty (Tarrow(arrow_desc, newmono ty_arg, ty_result, commu_ok))

0 commit comments

Comments
 (0)