File tree Expand file tree Collapse file tree 2 files changed +28
-6
lines changed Expand file tree Collapse file tree 2 files changed +28
-6
lines changed Original file line number Diff line number Diff line change @@ -1414,11 +1414,6 @@ FunctionType::ExtInfo ClosureEffectsRequest::evaluate(
1414
1414
bool async = expr->getAsyncLoc ().isValid ();
1415
1415
bool sendable = expr->getAttrs ().hasAttribute <SendableAttr>();
1416
1416
1417
- // `@concurrent` attribute is only valid on asynchronous function types.
1418
- if (expr->getAttrs ().hasAttribute <ConcurrentAttr>()) {
1419
- async = true ;
1420
- }
1421
-
1422
1417
if (throws || async) {
1423
1418
return ASTExtInfoBuilder ()
1424
1419
.withThrows (throws, /* FIXME:*/ Type ())
@@ -1432,11 +1427,17 @@ FunctionType::ExtInfo ClosureEffectsRequest::evaluate(
1432
1427
if (!body)
1433
1428
return ASTExtInfoBuilder ().withSendable (sendable).build ();
1434
1429
1430
+ // `@concurrent` attribute is only valid on asynchronous function types.
1431
+ bool asyncFromAttr = false ;
1432
+ if (expr->getAttrs ().hasAttribute <ConcurrentAttr>()) {
1433
+ asyncFromAttr = true ;
1434
+ }
1435
+
1435
1436
auto throwFinder = FindInnerThrows (expr);
1436
1437
body->walk (throwFinder);
1437
1438
return ASTExtInfoBuilder ()
1438
1439
.withThrows (throwFinder.foundThrow (), /* FIXME:*/ Type ())
1439
- .withAsync (bool (findAsyncNode (expr)))
1440
+ .withAsync (asyncFromAttr || bool (findAsyncNode (expr)))
1440
1441
.withSendable (sendable)
1441
1442
.build ();
1442
1443
}
Original file line number Diff line number Diff line change @@ -137,3 +137,24 @@ _ = { @MainActor @concurrent in
137
137
_ = { @concurrent ( ) -> Int in
138
138
// expected-error@-1 {{@concurrent on non-async closure}}
139
139
}
140
+
141
+ // Make sure that explicit use of `@concurrent` doesn't interfere with inference of `throws` from the body.
142
+ do {
143
+ func acceptsThrowing( _ body: ( ) async throws -> Void ) async {
144
+ }
145
+
146
+ struct Invocation {
147
+ func throwingFn( ) async throws {
148
+ }
149
+ }
150
+
151
+ func test( invocation: Invocation ) async {
152
+ await acceptsThrowing ( { @concurrent in try await invocation. throwingFn ( ) } ) // Ok
153
+ await acceptsThrowing ( { @concurrent [ invocation] in try await invocation. throwingFn ( ) } ) // Ok
154
+
155
+ await acceptsThrowing ( { @concurrent in // Ok
156
+ _ = 42
157
+ try await invocation. throwingFn ( )
158
+ } )
159
+ }
160
+ }
You can’t perform that action at this time.
0 commit comments