Skip to content

Commit 02dca7e

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 8dd08e7 commit 02dca7e

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
@@ -418,6 +418,7 @@ namespace {
418418
PAIRCASE (SpaceKind::BooleanConstant, SpaceKind::BooleanConstant):
419419
return this->getBoolValue() == other.getBoolValue();
420420

421+
PAIRCASE (SpaceKind::BooleanConstant, SpaceKind::Constructor):
421422
PAIRCASE (SpaceKind::BooleanConstant, SpaceKind::UnknownCase):
422423
return false;
423424

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)