Skip to content

Commit 5bbd126

Browse files
committed
Redo The Notes For "Uninhabited" Parameter Types
The use of the term 'uninhabited' does not make sense outside of formal type theoretic contexts. In Swift, we also do not use this term in a standard way - hence the term "structurally uninhabited" since we only consider products and sums eligible for the check. (Aside: We do not do exponentials because... well, Swift's type system implements Harper's "typerec" operator and as a consequence parametricity is just _not a thing_). I digress... So, improve upon the old diagnostic in two ways: 1) Do away with 'uninhabited' - instead, mention that it's either an enum or a tuple with an enum in it that 'has no cases' 2) Since the SIL parameter convention flattens all tuples, point directly at the offending uninhabited element type rdar://83600669
1 parent dd5e254 commit 5bbd126

File tree

3 files changed

+18
-7
lines changed

3 files changed

+18
-7
lines changed

include/swift/AST/DiagnosticsSIL.def

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,9 @@ ERROR(guard_body_must_not_fallthrough,none,
290290
" to exit the scope", ())
291291
WARNING(unreachable_code,none, "will never be executed", ())
292292
NOTE(unreachable_code_uninhabited_param_note,none,
293-
"'%0' is uninhabited, so this function body can never be executed", (StringRef))
293+
"'%0' is of type %1 which cannot be constructed because %select{it "
294+
"contains %3 which is an enum with no cases|it is an enum with no cases}2",
295+
(StringRef, Type, bool, Type))
294296
NOTE(unreachable_code_branch,none,
295297
"condition always evaluates to %select{false|true}0", (bool))
296298
NOTE(call_to_noreturn_note,none,

lib/SILGen/SILGenStmt.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,10 +358,19 @@ void StmtEmitter::visitBraceStmt(BraceStmt *S) {
358358
diag::unreachable_code);
359359
if (!S->getElements().empty()) {
360360
for (auto *arg : SGF.getFunction().getArguments()) {
361-
if (arg->getType().getASTType()->isStructurallyUninhabited()) {
361+
auto argTy = arg->getType().getASTType();
362+
if (argTy->isStructurallyUninhabited()) {
363+
// Use the interface type in this diagnostic because the SIL type
364+
// unpacks tuples. But, the SIL type being exploded means it
365+
// points directly at the offending tuple element type and we can
366+
// use that to point the user at problematic component(s).
367+
auto argIFaceTy = arg->getDecl()->getInterfaceType();
362368
diagnose(getASTContext(), S->getStartLoc(),
363369
diag::unreachable_code_uninhabited_param_note,
364-
arg->getDecl()->getBaseName().userFacingName());
370+
arg->getDecl()->getBaseName().userFacingName(),
371+
argIFaceTy,
372+
argIFaceTy->is<EnumType>(),
373+
argTy);
365374
break;
366375
}
367376
}

test/SILGen/functions_uninhabited_param.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
//===--- Function declaration with uninhabited parameter type
44

5-
func foo(baz: Never) -> Int { // expected-note {{'baz' is uninhabited, so this function body can never be executed}}
5+
func foo(baz: Never) -> Int { // expected-note {{'baz' is of type 'Never' which cannot be constructed because it is an enum with no cases}}
66
print("I can't be called!") // expected-warning{{will never be executed}}
77
return 0
88
}
@@ -11,11 +11,11 @@ func bar(baz: Never) -> Int {} // ok
1111

1212
// SR-13432
1313
func map<T>(_ block: (Never) -> T) {}
14-
map { arg in // expected-note {{'arg' is uninhabited, so this function body can never be executed}}
14+
map { arg in // expected-note {{'arg' is of type 'Never' which cannot be constructed because it is an enum with no cases}}
1515
5 // expected-warning {{will never be executed}}
1616
}
1717

18-
map { arg in // expected-note {{'arg' is uninhabited, so this function body can never be executed}}
18+
map { arg in // expected-note {{'arg' is of type 'Never' which cannot be constructed because it is an enum with no cases}}
1919
return 5 // expected-warning {{will never be executed}}
2020
}
2121

@@ -26,4 +26,4 @@ enum E {
2626

2727
let _: (E.Type) -> (E) -> () = { s in { e in s.f(e) } }
2828
// expected-warning@-1 {{will never be executed}}
29-
// expected-note@-2 {{'e' is uninhabited, so this function body can never be executed}}
29+
// expected-note@-2 {{'e' is of type 'E' which cannot be constructed because it is an enum with no cases}}

0 commit comments

Comments
 (0)