Skip to content

Commit 4369a71

Browse files
committed
Handle Boolean Patterns Matching Against Invalid Constructor Forms
The Space Engine maintains as one of its invariants that the AST it is handed must at least typecheck. When swift typechecks patterns, the only case one is allowed to form a Boolean pattern is when a literal is expected, and the corresponding type of the pattern clause is exactly Bool. This precludes the use of other types, including ExpressibleByBooleanLiteral types, from matching. Thus, this code path was never hit. That is, until we accidentally lifted the restriction on enum case base name overloading too early. Now, it is possible for the space engine to see the same constructor head that has subspaces with different argument types. The space engine is relatively tolerant of this bizarre situation, but in this one narrow case it was not. This patch has a narrow fix to add the missing case to the space engine. In the long term, we need to actually finish SE-0155 which will make this crash structurally impossible once again. Resolves rdar://65229620
1 parent 9c20198 commit 4369a71

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

lib/Sema/TypeCheckSwitchStmt.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,7 @@ namespace {
412412
PAIRCASE (SpaceKind::BooleanConstant, SpaceKind::BooleanConstant):
413413
return this->getBoolValue() == other.getBoolValue();
414414

415+
PAIRCASE (SpaceKind::BooleanConstant, SpaceKind::Constructor):
415416
PAIRCASE (SpaceKind::BooleanConstant, SpaceKind::UnknownCase):
416417
return false;
417418

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: not %target-swift-frontend -typecheck %s
2+
3+
// N.B.: Requires a no-asserts build to reproduce, otherwise this hits an
4+
// assertion in type check pattern.
5+
// REQUIRES: no_asserts
6+
7+
indirect enum BadOverload {
8+
case one(Bool, other: Void)
9+
case one(Bool?)
10+
}
11+
12+
func crash(_ x: BadOverload) {
13+
switch $0 {
14+
case .one(false?):
15+
break
16+
}
17+
}
18+

0 commit comments

Comments
 (0)