@@ -18,7 +18,7 @@ let with_effect : ((string -> unit) @ local yielding -> 'a) -> 'a =
1818
1919[%% expect{|
2020val 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>
2222|}]
2323
2424let () = with_effect (fun k -> k " Hello, world!" )
@@ -36,7 +36,7 @@ let () = with_effect (fun k -> run_yielding k)
3636let _ = ! storage
3737
3838[%% expect{|
39- val run_yielding : local_ (string -> unit ) @ yielding -> unit = < fun>
39+ val run_yielding : local_ (string -> unit ) -> unit = < fun>
4040- : string = "my string"
4141|}]
4242
@@ -45,25 +45,19 @@ let run_unyielding : (string -> unit) @ local unyielding -> unit = fun f -> f "a
4545let () = with_effect (fun k -> run_unyielding k)
4646
4747[%% expect{|
48- val run_unyielding : local_ (string -> unit ) -> unit = < fun>
48+ val run_unyielding : local_ (string -> unit ) @ unyielding -> unit = < fun>
4949Line 3 , characters 46-47 :
50503 | let () = with_effect (fun k -> run_unyielding k )
5151 ^
5252Error : This value is "yielding" but expected to be "unyielding" .
5353|}]
5454
55- (* CR dkalinichenko: default [local] arguments to [yielding]. *)
56-
5755let run_default : (string -> unit) @ local -> unit = fun f -> f " some string"
5856
5957let () = with_effect (fun k -> run_default k)
6058
6159[%% expect{|
6260val 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" .
6761|}]
6862
6963(* A closure over a [yielding] value must be [yielding]. *)
@@ -78,3 +72,121 @@ Line 2, characters 45-46:
7872 ^
7973Error : The value " k" is yielding, so cannot be used inside a function that may not yield.
8074| }]
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