@@ -125,17 +125,74 @@ struct IsolatedType {
125
125
@concurrent func test( ) async { }
126
126
}
127
127
128
- _ = { @concurrent in // Ok
128
+ // `@concurrent` on closures does not contribute to `async` inference.
129
+ do {
130
+ _ = { @concurrent in }
131
+ // expected-error@-1:9 {{cannot use @concurrent on non-async closure}}{{none}}
132
+ _ = { @concurrent ( ) -> Int in }
133
+ // expected-error@-1:9 {{cannot use @concurrent on non-async closure}}{{none}}
134
+ // Explicit effect precludes effects inference from the body.
135
+ _ = { @concurrent ( ) throws in await awaitMe ( ) }
136
+ // expected-error@-1:9 {{cannot use @concurrent on non-async closure}}{{none}}
137
+ // expected-error@-2:40 {{'async' call in a function that does not support concurrency}}{{none}}
138
+ _ = { @concurrent ( ) async in }
139
+ _ = { @concurrent in await awaitMe ( ) }
140
+
141
+ func awaitMe( ) async { }
142
+
143
+ do {
144
+ func foo( _: ( ) -> Void ) { }
145
+ func foo( _: ( ) async -> Void ) async { }
146
+
147
+ func sync( ) {
148
+ foo { @concurrent in }
149
+ // expected-error@-1:13 {{cannot use @concurrent on non-async closure}}{{none}}
150
+ }
151
+ // expected-note@+1:10 {{add 'async' to function 'sync2()' to make it asynchronous}}{{17-17= async}}
152
+ func sync2( ) {
153
+ foo { @concurrent in await awaitMe ( ) }
154
+ // expected-error@-1:7 {{'async' call in a function that does not support concurrency}}{{none}}
155
+ }
156
+ func async ( ) async {
157
+ // Even though the context is async, the sync overload is favored because
158
+ // the closure is sync, so the error is expected.
159
+ foo { @concurrent in }
160
+ // expected-error@-1:13 {{cannot use @concurrent on non-async closure}}{{none}}
161
+
162
+ foo { @concurrent in await awaitMe ( ) }
163
+ // expected-error@-1:7 {{expression is 'async' but is not marked with 'await'}}{{7-7=await }}
164
+ // expected-note@-2:7 {{call is 'async'}}{{none}}
165
+ }
166
+ }
167
+
168
+ do {
169
+ func foo( _: ( Int ) async -> Void ) { }
170
+ func foo( _: ( Int ) -> Void ) async { }
171
+
172
+ func sync( ) {
173
+ // OK, sync overload picked.
174
+ foo { @concurrent _ in }
175
+ }
176
+ func async ( ) async {
177
+ foo { @concurrent _ in }
178
+ // expected-error@-1:13 {{cannot use @concurrent on non-async closure}}{{none}}
179
+ // expected-error@-2:7 {{expression is 'async' but is not marked with 'await'}}{{7-7=await }}
180
+ // expected-note@-3:7 {{call is 'async'}}{{none}}
181
+ }
182
+ }
183
+
184
+ do {
185
+ func foo< T> ( _: T ) { }
186
+
187
+ foo ( { @concurrent in } )
188
+ // expected-error@-1:10 {{cannot use @concurrent on non-async closure}}{{none}}
189
+ }
129
190
}
130
191
131
192
_ = { @MainActor @concurrent in
132
193
// expected-error@-1 {{cannot use @concurrent because function type is isolated to a global actor 'MainActor'}}
133
194
}
134
195
135
- _ = { @concurrent ( ) -> Int in
136
- // expected-error@-1 {{@concurrent on non-async closure}}
137
- }
138
-
139
196
// Make sure that explicit use of `@concurrent` doesn't interfere with inference of `throws` from the body.
140
197
do {
141
198
func acceptsThrowing( _ body: ( ) async throws -> Void ) async {
0 commit comments