Skip to content

Commit 6a7b38d

Browse files
authored
[SILGenPattern] Silence redundant unreachable enum case warning (swiftlang#33336)
1 parent 83b2ebe commit 6a7b38d

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

lib/SILGen/SILGenPattern.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,20 +1038,35 @@ void PatternMatchEmission::emitDispatch(ClauseMatrix &clauses, ArgArray args,
10381038
SGF.eraseBasicBlock(contBB);
10391039
return;
10401040
}
1041-
1041+
10421042
// Otherwise, if there is no fallthrough, then the next row is
1043-
// unreachable: emit a dead code diagnostic.
1043+
// unreachable: emit a dead code diagnostic if:
1044+
// 1) It's for a 'default' case (since Space Engine already handles
1045+
// unreachable enum case patterns) or it's for a enum case which
1046+
// has expression patterns since redundancy checking for such
1047+
// patterns isn't sufficiently done by the Space Engine.
1048+
// 2) It's for a case statement in a do-catch.
10441049
if (!clauses[firstRow].hasFallthroughTo()) {
10451050
SourceLoc Loc;
10461051
bool isDefault = false;
1052+
bool isParentDoCatch = false;
1053+
bool caseHasExprPattern = false;
10471054
if (auto *S = clauses[firstRow].getClientData<Stmt>()) {
10481055
Loc = S->getStartLoc();
1049-
if (auto *CS = dyn_cast<CaseStmt>(S))
1056+
if (auto *CS = dyn_cast<CaseStmt>(S)) {
1057+
caseHasExprPattern = llvm::any_of(
1058+
CS->getCaseLabelItems(), [&](const CaseLabelItem item) {
1059+
return item.getPattern()->getKind() == PatternKind::Expr;
1060+
});
1061+
isParentDoCatch = CS->getParentKind() == CaseParentKind::DoCatch;
10501062
isDefault = CS->isDefault();
1063+
}
10511064
} else {
10521065
Loc = clauses[firstRow].getCasePattern()->getStartLoc();
10531066
}
1054-
SGF.SGM.diagnose(Loc, diag::unreachable_case, isDefault);
1067+
if (isParentDoCatch || isDefault || caseHasExprPattern) {
1068+
SGF.SGM.diagnose(Loc, diag::unreachable_case, isDefault);
1069+
}
10551070
}
10561071
}
10571072
}

test/SILGen/unreachable_code.swift

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,7 @@ func testUnreachableCase1(a : Tree) {
6767
case let Leaf:
6868
_ = Leaf
6969
return
70-
case .Branch(_): // expected-warning {{case will never be executed}}
71-
// expected-warning@-1 {{case is already handled by previous patterns; consider removing it}}
70+
case .Branch(_): // expected-warning {{case is already handled by previous patterns; consider removing it}}
7271
return
7372
}
7473
}
@@ -87,8 +86,7 @@ func testUnreachableCase3(a : Tree) {
8786
switch a {
8887
case _:
8988
break
90-
case .Branch(_): // expected-warning {{case will never be executed}}
91-
// expected-warning@-1 {{case is already handled by previous patterns; consider removing it}}
89+
case .Branch(_): // expected-warning {{case is already handled by previous patterns; consider removing it}}
9290
return
9391
}
9492
}
@@ -137,3 +135,14 @@ func sr6141() {
137135
return;
138136
bar?.append("x") // expected-warning{{code after 'return' will never be executed}}
139137
}
138+
139+
func testUnreachableCatchClause() {
140+
enum ErrorEnum: Error { case someError }
141+
do {
142+
throw ErrorEnum.someError
143+
} catch let error {
144+
print(error)
145+
} catch ErrorEnum.someError { // expected-warning {{case will never be executed}}
146+
print("some error")
147+
}
148+
}

0 commit comments

Comments
 (0)