Skip to content

Commit 18ef186

Browse files
committed
[Concurrency] Diagnose "try await" with a Fix-It
1 parent dd7ce80 commit 18ef186

File tree

11 files changed

+25
-17
lines changed

11 files changed

+25
-17
lines changed

include/swift/AST/DiagnosticsParse.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,6 +1222,8 @@ ERROR(super_in_closure_with_capture,none,
12221222
NOTE(super_in_closure_with_capture_here,none,
12231223
"'self' explicitly captured here", ())
12241224

1225+
ERROR(try_before_await,none, "'await' must precede 'try'", ())
1226+
12251227
// Tuples and parenthesized expressions
12261228
ERROR(expected_expr_in_expr_list,none,
12271229
"expected expression in list of expressions", ())

lib/Parse/ParseExpr.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,13 @@ ParserResult<Expr> Parser::parseExprSequenceElement(Diag<> message,
436436
: parseExprUnary(message, isExprBasic);
437437

438438
if (hadTry && !sub.hasCodeCompletion() && !sub.isNull()) {
439+
// "await" must precede "try".
440+
if (auto await = dyn_cast<AwaitExpr>(sub.get())) {
441+
diagnose(await->getLoc(), diag::try_before_await)
442+
.fixItRemove(await->getLoc())
443+
.fixItInsert(tryLoc, "await ");
444+
}
445+
439446
ElementContext.setCreateSyntax(SyntaxKind::TryExpr);
440447
switch (trySuffix ? trySuffix->getKind() : tok::NUM_TOKENS) {
441448
case tok::exclaim_postfix:

stdlib/public/Concurrency/PartialAsyncTask.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ public func withUnsafeContinuation<T>(
8989
public func withUnsafeThrowingContinuation<T>(
9090
_ fn: (UnsafeThrowingContinuation<T>) -> Void
9191
) async throws -> T {
92-
return try await Builtin.withUnsafeThrowingContinuation {
92+
return await try Builtin.withUnsafeThrowingContinuation {
9393
fn(UnsafeThrowingContinuation<T>($0))
9494
}
95-
}
95+
}

test/ClangImporter/objc_async.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import ObjCConcurrency
88
func testSlowServer(slowServer: SlowServer) async throws {
99
let _: Int = await slowServer.doSomethingSlow("mail")
1010
let _: Bool = await slowServer.checkAvailability()
11-
let _: String = try await slowServer.findAnswer()
11+
let _: String = await try slowServer.findAnswer()
1212
let _: String = await try slowServer.findAnswerFailingly()
1313
let _: Void = await slowServer.doSomethingFun("jump")
1414
let _: (Int) -> Void = slowServer.completionHandler

test/Concurrency/async_tasks.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,11 @@ func test_unsafeContinuations() async {
5454
}
5555

5656
func test_unsafeThrowingContinuations() async {
57-
let _: String = try await Task.withUnsafeThrowingContinuation { continuation in
57+
let _: String = await try Task.withUnsafeThrowingContinuation { continuation in
5858
continuation.resume(returning: "")
5959
}
6060

61-
let _: String = try await Task.withUnsafeThrowingContinuation { continuation in
61+
let _: String = await try Task.withUnsafeThrowingContinuation { continuation in
6262
continuation.resume(throwing: MyError())
6363
}
6464

test/IRGen/async.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public func task_future_wait(_ task: __owned SomeClass) async throws -> Int
1919
// CHECK: tail call swiftcc void @swift_task_future_wait(
2020
public func testThis(_ task: __owned SomeClass) async {
2121
do {
22-
let _ = try await task_future_wait(task)
22+
let _ = await try task_future_wait(task)
2323
} catch _ {
2424
print("error")
2525
}

test/SILGen/async_builtins.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public func usesWithUnsafeContinuation() async {
9393

9494
// CHECK-LABEL: sil [ossa] @$s4test34usesWithUnsafeThrowingContinuationyyYKF : $@convention(thin) @async () -> @error Error {
9595
public func usesWithUnsafeThrowingContinuation() async throws {
96-
let _: Int = try await Builtin.withUnsafeThrowingContinuation { c in }
96+
let _: Int = await try Builtin.withUnsafeThrowingContinuation { c in }
9797

9898
// CHECK: [[FN:%.*]] = function_ref @$s4test34usesWithUnsafeThrowingContinuationyyYKFyBcXEfU_ : $@convention(thin) (Builtin.RawUnsafeContinuation) -> ()
9999
// CHECK: [[TMP:%.*]] = convert_function [[FN]] : $@convention(thin) (Builtin.RawUnsafeContinuation) -> () to $@convention(thin) @noescape (Builtin.RawUnsafeContinuation) -> ()
@@ -117,4 +117,4 @@ public func usesWithUnsafeThrowingContinuation() async throws {
117117
// because it has captures and was formed by a partial_apply.
118118
public func usesWithUnsafeContinuationCaptures(fn: (Builtin.RawUnsafeContinuation) -> ()) async throws {
119119
let _: Int = await Builtin.withUnsafeContinuation { c in fn(c) }
120-
}
120+
}

test/SILGen/hop_to_executor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ actor class MyActor {
3434
// CHECK: } // end sil function '$s4test7MyActorC0A13AsyncFunctionyyYKF'
3535
func testAsyncFunction() async throws {
3636
await callee(p)
37-
try await throwingCallee(p)
37+
await try throwingCallee(p)
3838
}
3939

4040
// CHECK-LABEL: sil hidden [ossa] @$s4test7MyActorC0A22ConsumingAsyncFunctionyyYF : $@convention(method) @async (@owned MyActor) -> () {

test/SILGen/objc_async.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,16 @@ func testSlowServer(slowServer: SlowServer) async throws {
3737
// CHECK: [[RESULT:%.*]] = load [take] [[RESUME_BUF]]
3838
// CHECK: destroy_value [[RESULT]]
3939
// CHECK: dealloc_stack [[RESUME_BUF]]
40-
let _: String = try await slowServer.findAnswer()
40+
let _: String = await try slowServer.findAnswer()
4141

4242
// CHECK: objc_method {{.*}} $@convention(objc_method) (NSString, @convention(block) () -> (), SlowServer) -> ()
4343
// CHECK: [[BLOCK_IMPL:%.*]] = function_ref @[[VOID_COMPLETION_BLOCK:.*]] : $@convention(c) (@inout_aliasable @block_storage UnsafeContinuation<()>) -> ()
4444
await slowServer.serverRestart("somewhere")
4545

4646
// CHECK: [[BLOCK_IMPL:%.*]] = function_ref @[[NSSTRING_INT_THROW_COMPLETION_BLOCK:.*]] : $@convention(c) (@inout_aliasable @block_storage UnsafeThrowingContinuation<(String, Int)>, Optional<NSString>, Int, Optional<NSError>) -> ()
47-
let (_, _): (String, Int) = try await slowServer.findMultipleAnswers()
47+
let (_, _): (String, Int) = await try slowServer.findMultipleAnswers()
4848

49-
let (_, _): (Bool, Bool) = try await slowServer.findDifferentlyFlavoredBooleans()
49+
let (_, _): (Bool, Bool) = await try slowServer.findDifferentlyFlavoredBooleans()
5050

5151
// CHECK: [[ERROR]]([[ERROR_VALUE:%.*]] : @owned $Error):
5252
// CHECK: dealloc_stack [[RESUME_BUF]]

test/SILGen/objc_async_from_swift.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func testSlowServing(p: SlowServing) async throws {
2020
// CHECK: objc_method {{.*}} $@convention(objc_method) <τ_0_0 where τ_0_0 : SlowServing> (@convention(block) (Int, NSString) -> (), τ_0_0) -> ()
2121
let _: (Int, String) = await p.requestIntAndString()
2222
// CHECK: objc_method {{.*}} $@convention(objc_method) <τ_0_0 where τ_0_0 : SlowServing> (@convention(block) (Int, Optional<NSString>, Optional<NSError>) -> (), τ_0_0) -> ()
23-
let _: (Int, String) = try await p.tryRequestIntAndString()
23+
let _: (Int, String) = await try p.tryRequestIntAndString()
2424
}
2525

2626
/*

0 commit comments

Comments
 (0)