Skip to content

Commit fdaddcc

Browse files
committed
Uninhabited != NoReturn
Previously, isNever would return true for an equivalence class of uninhabited enums. The rest of the compiler, however, is using this in places that actually expect just the Never type. This means that code like this would compile properly enum Uninhabited {} func do() -> Uninhabited { /* No body here */ } and we wouldn’t diagnose the missing return.
1 parent 3757b36 commit fdaddcc

File tree

5 files changed

+9
-6
lines changed

5 files changed

+9
-6
lines changed

include/swift/AST/Types.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ class alignas(1 << TypeAlignInBits) TypeBase {
393393
/// semantics?
394394
bool hasReferenceSemantics();
395395

396-
/// Is this an uninhabited type, such as 'Never'?
396+
/// Is this 'Never'?
397397
bool isNever();
398398

399399
/// Is this the 'Any' type?

lib/AST/Type.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,7 @@ bool TypeBase::hasReferenceSemantics() {
9292
bool TypeBase::isNever() {
9393
if (auto nominalDecl = getAnyNominal())
9494
if (auto enumDecl = dyn_cast<EnumDecl>(nominalDecl))
95-
if (enumDecl->getAllElements().empty())
96-
return true;
97-
95+
return enumDecl == getASTContext().getNeverDecl();
9896
return false;
9997
}
10098

lib/IRGen/GenClangType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ GenClangType::visitBoundGenericType(CanBoundGenericType type) {
493493
clang::CanQualType GenClangType::visitEnumType(CanEnumType type) {
494494
// Special case: Uninhabited enums are not @objc, so we don't
495495
// know what to do below, but we can just convert to 'void'.
496-
if (type->isNever())
496+
if (type->getDecl()->getAllElements().empty())
497497
return Converter.convert(IGM, IGM.Context.TheEmptyTupleType);
498498

499499
assert(type->getDecl()->isObjC() && "not an @objc enum?!");

test/IRGen/dllexport.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public var ci : c = c()
2020

2121
open class d {
2222
private func m() -> Never {
23-
fatalError()
23+
return fatalError()
2424
}
2525
}
2626

test/SILOptimizer/return.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ func singleBlock2() -> Int {
99
y += 1
1010
} // expected-error {{missing return in a function expected to return 'Int'}}
1111

12+
enum NoCasesButNotNever {}
13+
14+
func diagnoseNoCaseEnumMissingReturn() -> NoCasesButNotNever {
15+
} // expected-error {{missing return in a function expected to return 'NoCasesButNotNever'}}
16+
1217
class MyClassWithClosure {
1318
var f : (_ s: String) -> String = { (_ s: String) -> String in } // expected-error {{missing return in a closure expected to return 'String'}}
1419
}

0 commit comments

Comments
 (0)