Skip to content

Commit 7ba8720

Browse files
committed
Don't try to put Tof_kind in a row variable
1 parent c044dd3 commit 7ba8720

File tree

6 files changed

+71
-25
lines changed

6 files changed

+71
-25
lines changed

testsuite/tests/typing-jkind-bounds/gadt.ml

+45
Original file line numberDiff line numberDiff line change
@@ -358,3 +358,48 @@ Error: The kind of type "box" is immutable_data with _
358358
But the kind of type "box" must be a subkind of immediate
359359
because of the annotation on the declaration of the type box.
360360
|}]
361+
362+
(* Existential row variables *)
363+
364+
type exist_row1 = Mk : ([< `A | `B of int ref] as 'a) -> exist_row1
365+
[%%expect{|
366+
type exist_row1 = Mk : [< `A | `B of int ref ] -> exist_row1
367+
|}]
368+
369+
let foo (x : exist_row1 @ nonportable) = use_portable x
370+
(* CR layouts v2.8: This should be accepted *)
371+
[%%expect{|
372+
Line 1, characters 54-55:
373+
1 | let foo (x : exist_row1 @ nonportable) = use_portable x
374+
^
375+
Error: This value is "nonportable" but expected to be "portable".
376+
|}]
377+
378+
let foo (x : exist_row1 @ contended) = use_uncontended x
379+
[%%expect{|
380+
Line 1, characters 55-56:
381+
1 | let foo (x : exist_row1 @ contended) = use_uncontended x
382+
^
383+
Error: This value is "contended" but expected to be "uncontended".
384+
|}]
385+
386+
type exist_row2 = Mk : ([> `A | `B of int ref] as 'a) -> exist_row2
387+
[%%expect{|
388+
type exist_row2 = Mk : [> `A | `B of int ref ] -> exist_row2
389+
|}]
390+
391+
let foo (x : exist_row1 @ nonportable) = use_portable x
392+
[%%expect{|
393+
Line 1, characters 54-55:
394+
1 | let foo (x : exist_row1 @ nonportable) = use_portable x
395+
^
396+
Error: This value is "nonportable" but expected to be "portable".
397+
|}]
398+
399+
let foo (x : exist_row1 @ contended) = use_uncontended x
400+
[%%expect{|
401+
Line 1, characters 55-56:
402+
1 | let foo (x : exist_row1 @ contended) = use_uncontended x
403+
^
404+
Error: This value is "contended" but expected to be "uncontended".
405+
|}]

typing/btype.ml

+7-3
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,7 @@ let set_static_row_name decl path =
256256
(* Utilities for type traversal *)
257257
(**********************************)
258258

259-
let fold_row f init row =
260-
let result =
259+
let fold_row_fields f init row =
261260
List.fold_left
262261
(fun init (_, fi) ->
263262
match row_field_repr fi with
@@ -266,7 +265,9 @@ let fold_row f init row =
266265
| _ -> init)
267266
init
268267
(row_fields row)
269-
in
268+
269+
let fold_row f init row =
270+
let result = fold_row_fields f init row in
270271
match get_desc (row_more row) with
271272
| Tvar _ | Tunivar _ | Tsubst _ | Tconstr _ | Tnil | Tof_kind _ ->
272273
begin match
@@ -277,6 +278,9 @@ let fold_row f init row =
277278
end
278279
| _ -> assert false
279280

281+
let iter_row_fields f row =
282+
fold_row_fields (fun () v -> f v) () row
283+
280284
let iter_row f row =
281285
fold_row (fun () v -> f v) () row
282286

typing/btype.mli

+3
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ val fold_type_expr: ('a -> type_expr -> 'a) -> 'a -> type_expr -> 'a
138138
val iter_row: (type_expr -> unit) -> row_desc -> unit
139139
(* Iteration on types in a row *)
140140
val fold_row: ('a -> type_expr -> 'a) -> 'a -> row_desc -> 'a
141+
val iter_row_fields: (type_expr -> unit) -> row_desc -> unit
142+
(* Iteration on fields in a row, excluding row variable *)
143+
val fold_row_fields: ('a -> type_expr -> 'a) -> 'a -> row_desc -> 'a
141144
val iter_abbrev: (type_expr -> unit) -> abbrev_memo -> unit
142145
(* Iteration on types in an abbreviation list *)
143146
val iter_type_expr_kind: (type_expr -> unit) -> (type_decl_kind -> unit)

typing/datarepr.ml

+13-18
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,22 @@ open Types
2121
open Btype
2222

2323
(* Simplified version of Ctype.free_vars *)
24-
let free_vars ?(param=false) ty =
24+
let free_vars ?(param=false) ?(include_row_variables=true) ty =
2525
let ret = ref TypeSet.empty in
2626
let rec loop ty =
2727
if try_mark_node ty then
2828
match get_desc ty with
2929
| Tvar _ ->
3030
ret := TypeSet.add ty !ret
3131
| Tvariant row ->
32-
iter_row loop row;
33-
if not (static_row row) then begin
34-
match get_desc (row_more row) with
35-
| Tvar _ when param -> ret := TypeSet.add ty !ret
36-
| _ -> loop (row_more row)
37-
end
32+
if include_row_variables
33+
then iter_row loop row
34+
else iter_row_fields loop row;
35+
if not (static_row row) && include_row_variables then begin
36+
match get_desc (row_more row) with
37+
| Tvar _ when param -> ret := TypeSet.add ty !ret
38+
| _ -> loop (row_more row)
39+
end
3840
(* XXX: What about Tobject ? *)
3941
| _ ->
4042
iter_type_expr loop ty
@@ -316,7 +318,7 @@ let unboxed_labels_of_type ty_path decl =
316318
| Type_record _
317319
| Type_variant _ | Type_abstract _ | Type_open -> []
318320

319-
let constructor_unbound_type_vars cstr =
321+
let constructor_unbound_type_vars_excluding_row_variables cstr =
320322
match cstr.cd_res with
321323
| None -> TypeSet.empty
322324
| Some res_ty ->
@@ -332,15 +334,8 @@ let constructor_unbound_type_vars cstr =
332334
| _ -> Misc.fatal_error "cd_res must be Tconstr"
333335
in
334336
let arg_vars_set =
335-
free_vars (newgenty (Ttuple (List.map (fun ty -> None, ty) tyl)))
337+
free_vars
338+
~include_row_variables:false
339+
(newgenty (Ttuple (List.map (fun ty -> None, ty) tyl)))
336340
in
337341
TypeSet.diff arg_vars_set bound_vars
338-
339-
let unbound_type_vars decl =
340-
match decl.type_kind with
341-
| Type_variant (cstrs, _, _) ->
342-
List.fold_left (fun res cstr ->
343-
TypeSet.union res (constructor_unbound_type_vars cstr))
344-
TypeSet.empty
345-
cstrs
346-
| _ -> TypeSet.empty

typing/datarepr.mli

+2-3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,5 @@ val constructor_existentials :
4747
- the existential variables introduced by the constructor
4848
*)
4949

50-
val constructor_unbound_type_vars : constructor_declaration -> Btype.TypeSet.t
51-
52-
val unbound_type_vars : type_declaration -> Btype.TypeSet.t
50+
val constructor_unbound_type_vars_excluding_row_variables
51+
: constructor_declaration -> Btype.TypeSet.t

typing/typedecl.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2028,7 +2028,7 @@ let rec update_decl_jkind env dpath decl =
20282028
| None -> `Args (decl.type_params @ ret_args), `Params (decl.type_params @ params), seen
20292029
| Some res ->
20302030
let existentials =
2031-
Datarepr.constructor_unbound_type_vars cstr
2031+
Datarepr.constructor_unbound_type_vars_excluding_row_variables cstr
20322032
|> Btype.TypeSet.to_seq
20332033
|> Seq.map Types.Transient_expr.type_expr
20342034
|> List.of_seq

0 commit comments

Comments
 (0)