Skip to content

Commit e83970c

Browse files
committed
[SILGen]: extend uninhabited parameter checks to self param
SILGenProlog contains logic to emit an unreachable location if a function contains a structurally uninhabited parameter. This change extends this logic to include the `self` parameter, so instance members of structurally uninhabited types will produce the same diagnostics and have the same SIL emission behavior.
1 parent f88b29b commit e83970c

File tree

2 files changed

+61
-14
lines changed

2 files changed

+61
-14
lines changed

lib/SILGen/SILGenProlog.cpp

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,20 +1382,28 @@ void SILGenFunction::emitProlog(
13821382

13831383
emitExpectedExecutorProlog();
13841384

1385-
// IMPORTANT: This block should be the last one in `emitProlog`,
1386-
// since it terminates BB and no instructions should be insterted after it.
1387-
// Emit an unreachable instruction if a parameter type is
1388-
// uninhabited
1389-
if (paramList) {
1390-
for (auto *param : *paramList) {
1391-
if (param->getTypeInContext()->isStructurallyUninhabited()) {
1392-
SILLocation unreachableLoc(param);
1393-
unreachableLoc.markAsPrologue();
1394-
B.createUnreachable(unreachableLoc);
1395-
break;
1396-
}
1397-
}
1398-
}
1385+
// Emits an unreachable instruction if a parameter type (including `self`) is
1386+
// uninhabited. Returns `true` if an unreachable location was created.
1387+
auto handleUninhabitedParam = [&](ParamDecl *param) -> bool {
1388+
if (!param->getTypeInContext()->isStructurallyUninhabited())
1389+
return false;
1390+
1391+
SILLocation unreachableLoc(param);
1392+
unreachableLoc.markAsPrologue();
1393+
B.createUnreachable(unreachableLoc);
1394+
return true;
1395+
};
1396+
1397+
// IMPORTANT: An unreachable block should be the last one in `emitProlog`,
1398+
// since it is a terminator and no instructions should be insterted after it.
1399+
if (selfParam)
1400+
if (handleUninhabitedParam(selfParam))
1401+
return;
1402+
1403+
if (paramList)
1404+
for (auto *param : *paramList)
1405+
if (handleUninhabitedParam(param))
1406+
return;
13991407
}
14001408

14011409
static void emitIndirectPackParameter(SILGenFunction &SGF,

test/SILGen/functions_uninhabited_param.swift

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,42 @@ func empty_custom_product(_ xs: (E, Int)) { // expected-note {{'xs' is of type '
4242
print() // expected-warning{{will never be executed}}
4343
}
4444

45+
//===--- Uninhabited self parameters
46+
47+
extension Never {
48+
var unreachableComputed: Int { // expected-note{{'self' is of type 'Never' which cannot be constructed because it is an enum with no cases}}
49+
42 // expected-warning{{will never be executed}}
50+
}
51+
52+
subscript(_ i: Int) -> Int { // expected-note{{'self' is of type 'Never' which cannot be constructed because it is an enum with no cases}}
53+
42 // expected-warning{{will never be executed}}
54+
}
55+
56+
func unreachableMethod() -> Int { // expected-note{{'self' is of type 'Never' which cannot be constructed because it is an enum with no cases}}
57+
42 // expected-warning{{will never be executed}}
58+
}
59+
60+
func unreachableMethodWithParam(_ x: Int) -> Int { // expected-note{{'self' is of type 'Never' which cannot be constructed because it is an enum with no cases}}
61+
42 // expected-warning{{will never be executed}}
62+
}
63+
64+
func unreachableMethodWithUninhabitedParam(_ p0: Int, _ p1: Self, _ p2: Never) -> Int { // expected-note{{'p1' is of type 'Never' which cannot be constructed because it is an enum with no cases}}
65+
42 // expected-warning{{will never be executed}}
66+
}
67+
68+
func unreachableWithNestedDecls() -> Int { // expected-note{{'self' is of type 'Never' which cannot be constructed because it is an enum with no cases}}
69+
func g() -> Int { 42 }
70+
let c = { g() } // expected-warning{{will never be executed}}
71+
return c()
72+
}
73+
}
74+
75+
protocol P {
76+
var prop: Int { get }
77+
func uncallable(_ n: Never)
78+
}
79+
80+
extension Never: P {
81+
var prop: Int { fatalError() }
82+
func uncallable(_ n: Never) {}
83+
}

0 commit comments

Comments
 (0)