Skip to content

Commit 3490c73

Browse files
authored
Merge pull request #80672 from hamishknight/interfate-type
[Sema] Try limit kicking interface type in `filterForEnumElement`
2 parents 1914573 + 805f25d commit 3490c73

File tree

3 files changed

+81
-5
lines changed

3 files changed

+81
-5
lines changed

lib/Sema/TypeCheckPattern.cpp

+19-5
Original file line numberDiff line numberDiff line change
@@ -90,25 +90,39 @@ filterForEnumElement(DeclContext *DC, SourceLoc UseLoc,
9090
ValueDecl *e = result.getValueDecl();
9191
assert(e);
9292

93-
// Skip if the enum element was referenced as an instance member
93+
// We only care about enum members, and must either have an EnumElementDecl,
94+
// or a VarDecl which could be wrapping an underlying enum element.
95+
// FIXME: We check this up-front to avoid kicking InterfaceTypeRequest
96+
// below to help workaround https://github.com/swiftlang/swift/issues/80657
97+
// for non-enum cases. The proper fix is to move this filtering logic
98+
// into the constraint system.
99+
if (!e->getDeclContext()->getSelfEnumDecl())
100+
continue;
101+
102+
auto *EED = dyn_cast<EnumElementDecl>(e);
103+
auto *VD = dyn_cast<VarDecl>(e);
104+
if (!EED && !VD)
105+
continue;
106+
107+
// Skip if referenced as an instance member
94108
if (unqualifiedLookup) {
95109
if (!result.getBaseDecl() ||
96110
!result.getBaseDecl()->getInterfaceType()->is<MetatypeType>()) {
97111
continue;
98112
}
99113
}
100114

101-
if (auto *oe = dyn_cast<EnumElementDecl>(e)) {
115+
if (EED) {
102116
// Note that there could be multiple elements with the same
103117
// name, such results in a re-declaration error, so let's
104118
// just always pick the last element, just like in `foundConstant`
105119
// case.
106-
foundElement = oe;
120+
foundElement = EED;
107121
continue;
108122
}
109123

110-
if (auto *var = dyn_cast<VarDecl>(e)) {
111-
foundConstant = var;
124+
if (VD) {
125+
foundConstant = VD;
112126
continue;
113127
}
114128
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: not --crash %target-swift-frontend -emit-sil %s
2+
3+
// https://github.com/swiftlang/swift/issues/80657
4+
enum E {
5+
case e
6+
7+
static func foo() {
8+
_ = { [self] in
9+
switch e {
10+
case e:
11+
break
12+
default:
13+
break
14+
}
15+
}
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: %target-swift-frontend -emit-sil %s
2+
3+
// These cases are similar to https://github.com/swiftlang/swift/issues/80657,
4+
// but we can avoid hitting the same issue for non-enum members.
5+
6+
struct S {
7+
let y = 0
8+
func foo(_ x: Int) {
9+
let _ = { [self] in
10+
switch x {
11+
case y: break
12+
default: break
13+
}
14+
}
15+
}
16+
}
17+
18+
class C {
19+
let y = 0
20+
func foo(_ x: Int) {
21+
let _ = { [self] in
22+
switch x {
23+
case y: break
24+
default: break
25+
}
26+
}
27+
}
28+
}
29+
30+
enum E {
31+
case e
32+
33+
func bar() -> Int {0}
34+
35+
func foo() {
36+
_ = { [self] in
37+
switch 0 {
38+
case bar():
39+
break
40+
default:
41+
break
42+
}
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)