Skip to content

Commit bc2db04

Browse files
authored
flambda-backend: Refactor arrow modes printing (#2396)
* refactor curry printing * move the logic of legacy mode to printtyp.ml * address comments * better name
1 parent 729bf71 commit bc2db04

File tree

12 files changed

+209
-232
lines changed

12 files changed

+209
-232
lines changed

testsuite/tests/typing-implicit-source-positions/invalid_usages.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Line 1, characters 14-15:
4444
^
4545
Error: This expression has type call_pos:[%call_pos] -> unit -> unit
4646
but an expression was expected of type
47-
call_pos:Lexing.position -> (unit -> 'a)
47+
call_pos:Lexing.position -> unit -> 'a
4848
|}]
4949

5050
let h ?(call_pos:[%call_pos]) () = ()

testsuite/tests/typing-modal-kinds/basics.ml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,3 +595,13 @@ Line 2, characters 71-72:
595595
^
596596

597597
|}]
598+
599+
(* CR layouts: this should succeed. *)
600+
let foo : (string -> string) -> (string -> string) @ unique
601+
= fun f -> f
602+
[%%expect{|
603+
Line 2, characters 13-14:
604+
2 | = fun f -> f
605+
^
606+
Error: Found a shared value where a unique value was expected
607+
|}]

testsuite/tests/typing-modes/modes.ml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,18 +161,18 @@ Error: Found a shared value where a unique value was expected
161161
(* arrow types *)
162162
type r = local_ string @ unique once -> unique_ string @ local once
163163
[%%expect{|
164-
type r = local_ unique_ once_ string -> local_ unique_ once_ string
164+
type r = local_ once_ unique_ string -> local_ once_ unique_ string
165165
|}]
166166

167167
type r = local_ string * y:string @ unique once -> local_ string * w:string @ once
168168
[%%expect{|
169-
type r = local_ unique_ once_ string * string -> local_ once_ string * string
169+
type r = local_ once_ unique_ string * string -> local_ once_ string * string
170170
|}]
171171

172172
type r = x:local_ string * y:string @ unique once -> local_ string * w:string @ once
173173
[%%expect{|
174174
type r =
175-
x:local_ unique_ once_ string * string -> local_ once_ string * string
175+
x:local_ once_ unique_ string * string -> local_ once_ string * string
176176
|}]
177177

178178

@@ -250,12 +250,12 @@ type r = { global_ x : string; }
250250

251251
let foo ?(local_ x @ unique once = 42) () = ()
252252
[%%expect{|
253-
val foo : ?x:local_ unique_ once_ int -> unit -> unit = <fun>
253+
val foo : ?x:local_ once_ unique_ int -> unit -> unit = <fun>
254254
|}]
255255

256256
let foo ?(local_ x : _ @@ unique once = 42) () = ()
257257
[%%expect{|
258-
val foo : ?x:local_ unique_ once_ int -> unit -> unit = <fun>
258+
val foo : ?x:local_ once_ unique_ int -> unit -> unit = <fun>
259259
|}]
260260

261261
let foo ?(local_ x : 'a. 'a -> 'a @@ unique once) = ()
@@ -268,12 +268,12 @@ Error: Optional parameters cannot be polymorphic
268268

269269
let foo ?x:(local_ (x,y) @ unique once = (42, 42)) () = ()
270270
[%%expect{|
271-
val foo : ?x:local_ unique_ once_ int * int -> unit -> unit = <fun>
271+
val foo : ?x:local_ once_ unique_ int * int -> unit -> unit = <fun>
272272
|}]
273273

274274
let foo ?x:(local_ (x,y) : _ @@ unique once = (42, 42)) () = ()
275275
[%%expect{|
276-
val foo : ?x:local_ unique_ once_ int * int -> unit -> unit = <fun>
276+
val foo : ?x:local_ once_ unique_ int * int -> unit -> unit = <fun>
277277
|}]
278278

279279
let foo ?x:(local_ (x,y) : 'a.'a->'a @@ unique once) () = ()

testsuite/tests/typing-unique/unique_typedecl.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ Lines 3-4, characters 0-68:
3737
4 | = 'a -> unique_ 'b -> unique_ once_ ('c -> unique_ once_ ('d -> 'e))
3838
Error: The type constraints are not consistent.
3939
Type 'a -> unique_ 'b -> 'c -> 'd -> 'e is not compatible with type
40-
'a -> unique_ 'b -> unique_ once_ ('c -> unique_ once_ ('d -> 'e))
40+
'a -> unique_ 'b -> once_ unique_ ('c -> once_ unique_ ('d -> 'e))
4141
Type unique_ 'b -> 'c -> 'd -> 'e is not compatible with type
42-
unique_ 'b -> unique_ once_ ('c -> unique_ once_ ('d -> 'e))
42+
unique_ 'b -> once_ unique_ ('c -> once_ unique_ ('d -> 'e))
4343
|}]
4444

4545
type distinct_sarg = unit constraint unique_ int -> int = int -> int

typing/ctype.ml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,6 +1588,27 @@ let with_locality locality m =
15881588
Alloc.submode_exn (Alloc.meet_with (Comonadic Areality) Locality.Const.min m) m';
15891589
m'
15901590

1591+
let curry_mode alloc arg : Alloc.Const.t =
1592+
let acc =
1593+
Alloc.Const.join
1594+
(Alloc.Const.close_over arg)
1595+
(Alloc.Const.partial_apply alloc)
1596+
in
1597+
(* For A -> B -> C, we always interpret (B -> C) to be of shared. This is the
1598+
legacy mode which helps with legacy compatibility. Arrow types cross
1599+
uniqueness so we are not losing too much expressvity here. One
1600+
counter-example is:
1601+
1602+
let g : (A -> B -> C) = ...
1603+
let f (g : A -> unique_ (B -> C)) = ...
1604+
1605+
And [f g] would not work, as mode crossing doesn't work deeply into arrows.
1606+
Our answer to this issue is that, the author of f shouldn't ask B -> C to be
1607+
unique_. Instead, they should leave it as default which is shared, and mode
1608+
crossing it to unique at the location where B -> C is a real value (instead
1609+
of the return of a function). *)
1610+
{acc with uniqueness=Uniqueness.Const.Shared}
1611+
15911612
let rec instance_prim_locals locals mvar macc finalret ty =
15921613
match locals, get_desc ty with
15931614
| l :: locals, Tarrow ((lbl,marg,mret),arg,ret,commu) ->

typing/ctype.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,11 @@ val instance_prim:
212212
Primitive.description -> type_expr ->
213213
type_expr * Mode.Locality.lr option * Jkind.Sort.t option
214214

215+
(** Given (a @ m1 -> b -> c) @ m0, where [m0] and [m1] are modes expressed by
216+
user-syntax, [curry_mode m0 m1] gives the mode we implicitly interpret b->c
217+
to have. *)
218+
val curry_mode : Alloc.Const.t -> Alloc.Const.t -> Alloc.Const.t
219+
215220
val apply:
216221
?use_current_level:bool ->
217222
Env.t -> type_expr list -> type_expr -> type_expr list -> type_expr

typing/mode.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,6 +2108,13 @@ module Alloc = struct
21082108
{ locality; uniqueness; linearity }
21092109
end
21102110

2111+
let diff m0 m1 =
2112+
let diff le a0 a1 = if le a0 a1 && le a1 a0 then None else Some a0 in
2113+
let locality = diff Locality.Const.le m0.locality m1.locality in
2114+
let linearity = diff Linearity.Const.le m0.linearity m1.linearity in
2115+
let uniqueness = diff Uniqueness.Const.le m0.uniqueness m1.uniqueness in
2116+
{ locality; linearity; uniqueness }
2117+
21112118
(** See [Alloc.close_over] for explanation. *)
21122119
let close_over m =
21132120
let { monadic; comonadic } = split m in

typing/mode_intf.mli

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,10 @@ module type S = sig
358358
val value : t -> default:some -> some
359359
end
360360

361+
(** [diff a b] returns [None] for axes where [a] and [b] match, and [Some
362+
a0] for axes where [a] is [a0] and [b] isn't. *)
363+
val diff : t -> t -> Option.t
364+
361365
(** Similar to [Alloc.close_over] but for constants *)
362366
val close_over : t -> t
363367

0 commit comments

Comments
 (0)