Skip to content

Commit 8fbee40

Browse files
authored
Merge pull request swiftlang#10150 from CodaFi/sugar-booger
2 parents 4bfa2bf + 09c3f8f commit 8fbee40

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

lib/Sema/TypeCheckSwitchStmt.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,17 @@ namespace {
134134
}
135135

136136
public:
137-
explicit Space(Type T)
137+
explicit
138+
Space(Type T)
138139
: Kind(SpaceKind::Type), TypeAndVal(T, false), Head(Identifier()),
139140
Spaces({}){}
140141
explicit Space(Type T, Identifier H, bool downgrade, SmallVectorImpl<Space> &SP)
141142
: Kind(SpaceKind::Constructor), TypeAndVal(T, downgrade), Head(H),
142143
Spaces(SP.begin(), SP.end()) {}
144+
explicit Space(Type T, Identifier H, bool downgrade,
145+
const std::forward_list<Space> &SP)
146+
: Kind(SpaceKind::Constructor), TypeAndVal(T, downgrade), Head(H),
147+
Spaces(SP.begin(), SP.end()) {}
143148
explicit Space(SmallVectorImpl<Space> &SP)
144149
: Kind(SpaceKind::Disjunct), TypeAndVal(Type(), false),
145150
Head(Identifier()), Spaces(SP.begin(), SP.end()) {}
@@ -1267,6 +1272,14 @@ namespace {
12671272
}
12681273
case PatternKind::OptionalSome: {
12691274
auto *OSP = cast<OptionalSomePattern>(item);
1275+
auto subSpace = projectPattern(TC, OSP->getSubPattern(), sawDowngradablePattern);
1276+
// To match patterns like (_, _, ...)?, we must rewrite the underlying
1277+
// tuple pattern to .some(_, _, ...) first.
1278+
if (subSpace.getKind() == SpaceKind::Constructor
1279+
&& subSpace.getHead().empty()) {
1280+
return Space(item->getType(), TC.Context.getIdentifier("some"),
1281+
/*canDowngrade*/false, subSpace.getSpaces());
1282+
}
12701283
SmallVector<Space, 1> payload = {
12711284
projectPattern(TC, OSP->getSubPattern(), sawDowngradablePattern)
12721285
};

test/Sema/exhaustive_switch.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@ func foo(a: Int?, b: Int?) -> Int {
66
case (_, .none): return 2
77
case (.some(_), .some(_)): return 3
88
}
9+
10+
switch (a, b) {
11+
case (.none, _): return 1
12+
case (_, .none): return 2
13+
case (_?, _?): return 3
14+
}
15+
16+
switch Optional<(Int?, Int?)>.some((a, b)) {
17+
case .none: return 1
18+
case let (_, x?)?: return x
19+
case let (x?, _)?: return x
20+
case (.none, .none)?: return 0
21+
}
922
}
1023

1124
func bar(a: Bool, b: Bool) -> Int {
@@ -47,6 +60,15 @@ func foo() {
4760
case (_, .B(_)):
4861
()
4962
}
63+
64+
switch (Foo.A(1), Optional<(Int, Int)>.some((0, 0))) {
65+
case (.A(_), _):
66+
break
67+
case (.B(_), (let q, _)?):
68+
print(q)
69+
case (.B(_), nil):
70+
break
71+
}
5072
}
5173

5274
class C {}

0 commit comments

Comments
 (0)