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(
14141414 bool async = expr->getAsyncLoc ().isValid ();
14151415 bool sendable = expr->getAttrs ().hasAttribute <SendableAttr>();
14161416
1417- // `@concurrent` attribute is only valid on asynchronous function types.
1418- if (expr->getAttrs ().hasAttribute <ConcurrentAttr>()) {
1419- async = true ;
1420- }
1421-
14221417 if (throws || async) {
14231418 return ASTExtInfoBuilder ()
14241419 .withThrows (throws, /* FIXME:*/ Type ())
@@ -1432,11 +1427,17 @@ FunctionType::ExtInfo ClosureEffectsRequest::evaluate(
14321427 if (!body)
14331428 return ASTExtInfoBuilder ().withSendable (sendable).build ();
14341429
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+
14351436 auto throwFinder = FindInnerThrows (expr);
14361437 body->walk (throwFinder);
14371438 return ASTExtInfoBuilder ()
14381439 .withThrows (throwFinder.foundThrow (), /* FIXME:*/ Type ())
1439- .withAsync (bool (findAsyncNode (expr)))
1440+ .withAsync (asyncFromAttr || bool (findAsyncNode (expr)))
14401441 .withSendable (sendable)
14411442 .build ();
14421443}
Original file line number Diff line number Diff line change @@ -137,3 +137,24 @@ _ = { @MainActor @concurrent in
137137_ = { @concurrent ( ) -> Int in
138138 // expected-error@-1 {{@concurrent on non-async closure}}
139139}
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