Skip to content

Commit 1b1c507

Browse files
authored
Merge pull request #58611 from ahoppen/pr/fix-switch-refactoring
[Refactoring] Fix a crash that occurred when converting if/else of enum with raw value to switch statement
2 parents 0d6abf3 + e835c4a commit 1b1c507

File tree

4 files changed

+62
-9
lines changed

4 files changed

+62
-9
lines changed

lib/IDE/Refactoring.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2514,14 +2514,24 @@ bool RefactoringActionConvertToSwitchStmt::performChange() {
25142514
SourceManager &SM;
25152515

25162516
bool isFunctionNameAllowed(BinaryExpr *E) {
2517-
auto FunctionBody = dyn_cast<DotSyntaxCallExpr>(E->getFn())->getFn();
2518-
auto FunctionDeclaration = dyn_cast<DeclRefExpr>(FunctionBody)->getDecl();
2519-
const auto FunctionName = dyn_cast<FuncDecl>(FunctionDeclaration)
2520-
->getBaseIdentifier().str();
2521-
return FunctionName == "~="
2522-
|| FunctionName == "=="
2523-
|| FunctionName == "__derived_enum_equals"
2524-
|| FunctionName == "__derived_struct_equals";
2517+
Expr *Fn = E->getFn();
2518+
if (auto DotSyntaxCall = dyn_cast_or_null<DotSyntaxCallExpr>(Fn)) {
2519+
Fn = DotSyntaxCall->getFn();
2520+
}
2521+
DeclRefExpr *DeclRef = dyn_cast_or_null<DeclRefExpr>(Fn);
2522+
if (!DeclRef) {
2523+
return false;
2524+
}
2525+
auto FunctionDeclaration = dyn_cast_or_null<FuncDecl>(DeclRef->getDecl());
2526+
if (!FunctionDeclaration) {
2527+
return false;
2528+
}
2529+
auto &ASTCtx = FunctionDeclaration->getASTContext();
2530+
const auto FunctionName = FunctionDeclaration->getBaseIdentifier();
2531+
return FunctionName == ASTCtx.Id_MatchOperator ||
2532+
FunctionName == ASTCtx.Id_EqualsOperator ||
2533+
FunctionName == ASTCtx.Id_derived_enum_equals ||
2534+
FunctionName == ASTCtx.Id_derived_struct_equals;
25252535
}
25262536

25272537
void appendPattern(Expr *LHS, Expr *RHS) {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
enum EnumWithUnderlyingValue: String {
2+
case north, south, east, west
3+
}
4+
5+
6+
7+
func foo(test: EnumWithUnderlyingValue) {
8+
switch test {
9+
case .north:
10+
print("north")
11+
case .south:
12+
print("south")
13+
case .east:
14+
print("east")
15+
default:
16+
break
17+
}
18+
}
19+
20+
21+

test/refactoring/ConvertToSwitchStmt/basic.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func checkEmptyBody(e: E) {
131131
}
132132
}
133133

134-
// RUN: rm -rf %t.result && mkdir -p %t.result
134+
// RUN: %empty-directory(%t.result)
135135

136136
// RUN: %refactor -convert-to-switch-stmt -source-filename %s -pos=9:3 -end-pos=16:4 > %t.result/L9-3.swift
137137
// RUN: %target-swift-frontend-typecheck %t.result/L9-3.swift
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
enum EnumWithUnderlyingValue: String {
2+
case north, south, east, west
3+
}
4+
5+
6+
7+
func foo(test: EnumWithUnderlyingValue) {
8+
if test == .north {
9+
print("north")
10+
} else if test == .south {
11+
print("south")
12+
} else if test == .east {
13+
print("east")
14+
}
15+
}
16+
17+
18+
// RUN: %empty-directory(%t.result)
19+
20+
// RUN: %refactor -convert-to-switch-stmt -source-filename %s -pos=8:3 -end-pos=14:4 > %t.result/L8-3.swift
21+
// RUN: %target-swift-frontend-typecheck %t.result/L8-3.swift
22+
// RUN: diff -u %S/Outputs/enum_with_raw_value/L8-3.swift.expected %t.result/L8-3.swift

0 commit comments

Comments
 (0)