@@ -18,7 +18,7 @@ let with_effect : ((string -> unit) @ local yielding -> 'a) -> 'a =
18
18
19
19
[%% expect{|
20
20
val storage : string ref = {contents = " " }
21
- val with_effect : (local_ (string -> unit ) @ yielding -> 'a ) -> 'a = < fun>
21
+ val with_effect : (local_ (string -> unit ) -> 'a ) -> 'a = < fun>
22
22
|}]
23
23
24
24
let () = with_effect (fun k -> k " Hello, world!" )
@@ -36,7 +36,7 @@ let () = with_effect (fun k -> run_yielding k)
36
36
let _ = ! storage
37
37
38
38
[%% expect{|
39
- val run_yielding : local_ (string -> unit ) @ yielding -> unit = < fun>
39
+ val run_yielding : local_ (string -> unit ) -> unit = < fun>
40
40
- : string = "my string"
41
41
|}]
42
42
@@ -45,25 +45,19 @@ let run_unyielding : (string -> unit) @ local unyielding -> unit = fun f -> f "a
45
45
let () = with_effect (fun k -> run_unyielding k)
46
46
47
47
[%% expect{|
48
- val run_unyielding : local_ (string -> unit ) -> unit = < fun>
48
+ val run_unyielding : local_ (string -> unit ) @ unyielding -> unit = < fun>
49
49
Line 3 , characters 46-47 :
50
50
3 | let () = with_effect (fun k -> run_unyielding k )
51
51
^
52
52
Error : This value is "yielding" but expected to be "unyielding" .
53
53
|}]
54
54
55
- (* CR dkalinichenko: default [local] arguments to [yielding]. *)
56
-
57
55
let run_default : (string -> unit) @ local -> unit = fun f -> f " some string"
58
56
59
57
let () = with_effect (fun k -> run_default k)
60
58
61
59
[%% expect{|
62
60
val run_default : local_ (string -> unit ) -> unit = < fun>
63
- Line 3 , characters 43-44 :
64
- 3 | let () = with_effect (fun k -> run_default k )
65
- ^
66
- Error : This value is "yielding" but expected to be "unyielding" .
67
61
|}]
68
62
69
63
(* A closure over a [yielding] value must be [yielding]. *)
@@ -78,3 +72,121 @@ Line 2, characters 45-46:
78
72
^
79
73
Error : The value " k" is yielding, so cannot be used inside a function that may not yield.
80
74
| }]
75
+
76
+
77
+ type 'a t1 = Mk1 of 'a @@ global
78
+
79
+ type 'a t2 = Mk2 of 'a @@ global yielding
80
+
81
+ type 'a t3 = Mk3 of 'a @@ unyielding
82
+
83
+ type 'a t4 = Mk4 of 'a @@ yielding
84
+
85
+ let with_global_effect : ((string -> unit) @ yielding -> 'a) -> 'a =
86
+ fun f -> f ((:= ) storage)
87
+
88
+ [%% expect{|
89
+ type 'a t1 = Mk1 of global_ 'a
90
+ type 'a t2 = Mk2 of global_ 'a @@ yielding
91
+ type 'a t3 = Mk3 of 'a @@ unyielding
92
+ type 'a t4 = Mk4 of 'a
93
+ val with_global_effect : ((string -> unit ) @ yielding -> 'a ) -> 'a = < fun>
94
+ |}]
95
+
96
+ (* [global] modality implies [unyielding]. *)
97
+ let _ = with_global_effect (fun k -> let _ = Mk1 k in () )
98
+
99
+ [%% expect{|
100
+ Line 1 , characters 49-50 :
101
+ 1 | let _ = with_global_effect (fun k -> let _ = Mk1 k in () )
102
+ ^
103
+ Error : This value is "yielding" but expected to be "unyielding" .
104
+ |}]
105
+
106
+ (* [global yielding ] works : * )
107
+ let _ = with_global_effect (fun k -> let _ = Mk2 k in () )
108
+
109
+ [%% expect{|
110
+ - : unit = ()
111
+ | }]
112
+
113
+ (* [unyielding ] and [yielding ] modalities : * )
114
+ let _ = with_global_effect (fun k -> let _ = Mk3 k in () )
115
+
116
+ [%% expect{|
117
+ Line 1 , characters 49-50 :
118
+ 1 | let _ = with_global_effect (fun k -> let _ = Mk3 k in () )
119
+ ^
120
+ Error : This value is "yielding" but expected to be "unyielding" .
121
+ |}]
122
+
123
+ let _ = with_global_effect (fun k -> let _ = Mk4 k in () )
124
+
125
+ [%% expect{|
126
+ - : unit = ()
127
+ | }]
128
+
129
+ (* [@local_opt ] and [yielding ]: * )
130
+
131
+ external id : ('a [@local_opt ]) -> ('a[@ local_opt]) = " %identity"
132
+
133
+ let f1 x = id x
134
+ let f2 (x @ local ) = exclave_ id x
135
+ let f3 (x @ yielding ) = id x
136
+ let f4 (x @ local unyielding ) = exclave_ id x
137
+
138
+ [%% expect{|
139
+ external id : ('a [@ local_opt]) -> ('a [@ local_opt]) = " %identity"
140
+ val f1 : 'a -> 'a = < fun>
141
+ val f2 : local_ 'a -> local_ 'a = < fun>
142
+ val f3 : 'a @ yielding -> 'a @ yielding = < fun>
143
+ val f4 : local_ 'a @ unyielding -> local_ 'a @ unyielding = < fun>
144
+ |}]
145
+
146
+ (* [mod global] implies [mod unyielding] by default. *)
147
+
148
+ type ('a : value mod global) u1
149
+
150
+ type ('a : value mod global yielding) u2
151
+
152
+ type w1 : value mod global yielding
153
+
154
+ type w2 : value mod global unyielding
155
+
156
+ [%% expect{|
157
+ type ('a : value mod global) u1
158
+ type ('a : value mod global) u2
159
+ type w1 : value mod global
160
+ type w2 : value mod global
161
+ |}]
162
+
163
+ type _z1 = w1 u1
164
+
165
+ [%% expect{|
166
+ Line 1 , characters 11-13 :
167
+ 1 | type _z1 = w1 u1
168
+ ^^
169
+ Error : This type " w1" should be an instance of type " ('a : value mod global)"
170
+ The kind of w1 is value mod global
171
+ because of the definition of w1 at line 5 , characters 0 -35.
172
+ But the kind of w1 must be a subkind of value mod global
173
+ because of the definition of u1 at line 1 , characters 0 -31.
174
+ | }]
175
+
176
+ type _z2 = w2 u1
177
+
178
+ [%% expect{|
179
+ type _z2 = w2 u1
180
+ |}]
181
+
182
+ type _z3 = w1 u2
183
+
184
+ [%% expect{|
185
+ type _z3 = w1 u2
186
+ |}]
187
+
188
+ type _z4 = w2 u2
189
+
190
+ [%% expect{|
191
+ type _z4 = w2 u2
192
+ |}]
0 commit comments