Skip to content

Commit 5d86174

Browse files
committed
[Refactoring] Fix crash when refactoring protocol requirement to async
When a function declaration has no body (e.g. because it’s a protocol requirement), we construct the range to replace by the `async` keyword as follows: - Start: One character after the closing `)` (or potentially the `throws` keyword if it exists) - End: Last token in the function declaration Since the last token in the function declaration is the `)`, we end up with a range that has `End < Start`, which crashes when trying to print the range. If the function has no body, we should just use the range’s start location as the end location to construct an empty range. Fixes rdar://76677035
1 parent 47ca24d commit 5d86174

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

lib/IDE/Refactoring.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4914,7 +4914,7 @@ class AsyncConverter : private SourceEntityWalker {
49144914
RightStartLoc = Lexer::getLocForEndOfToken(SM, FD->getThrowsLoc());
49154915
}
49164916
SourceLoc RightEndLoc =
4917-
FD->getBody() ? FD->getBody()->getLBraceLoc() : FD->getEndLoc();
4917+
FD->getBody() ? FD->getBody()->getLBraceLoc() : RightStartLoc;
49184918
addRange(RightStartLoc, RightEndLoc);
49194919
return;
49204920
}

test/refactoring/ConvertAsync/basic.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,9 +150,15 @@ struct MyStruct {
150150
func retStruct() -> MyStruct { return MyStruct() }
151151

152152
protocol MyProtocol {
153-
// RUN: %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=PROTO-MEMBER %s
153+
// RUN: %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+2):3 | %FileCheck -check-prefix=PROTO-MEMBER %s
154+
// RUN: %refactor -convert-to-async -dump-text -source-filename %s -pos=%(line+1):3 | %FileCheck -check-prefix=PROTO-MEMBER-TO-ASYNC %s
154155
func protoMember(completion: (String) -> Void)
155156
// PROTO-MEMBER: func protoMember() async -> String{{$}}
157+
158+
// FIXME: The current async refactoring only refactors the client side and thus only adds the 'async' keyword.
159+
// We should be refactoring the entire method signature here and removing the completion parameter.
160+
// This test currently checks that we are not crashing.
161+
// PROTO-MEMBER-TO-ASYNC: func protoMember(completion: (String) -> Void) async
156162
}
157163

158164
// RUN: not %refactor -add-async-alternative -dump-text -source-filename %s -pos=%(line+1):1

0 commit comments

Comments
 (0)