mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Sema] Non-exhaustive switch statements are always an error in Swift 6.
This commit is contained in:
@@ -7074,10 +7074,9 @@ WARNING(redundant_particular_literal_case,none,
|
||||
NOTE(redundant_particular_literal_case_here,none,
|
||||
"first occurrence of identical literal pattern is here", ())
|
||||
|
||||
WARNING(non_exhaustive_switch_warn,none, "switch must be exhaustive", ())
|
||||
WARNING(non_exhaustive_switch_unknown_only,none,
|
||||
"switch covers known cases, but %0 may have additional unknown values"
|
||||
"%select{|, possibly added in future versions}1", (Type, bool))
|
||||
ERROR(non_exhaustive_switch_unknown_only,none,
|
||||
"switch covers known cases, but %0 may have additional unknown values"
|
||||
"%select{|, possibly added in future versions}1", (Type, bool))
|
||||
|
||||
ERROR(override_nsobject_hashvalue_error,none,
|
||||
"'NSObject.hashValue' is not overridable; "
|
||||
|
||||
@@ -1128,13 +1128,13 @@ namespace {
|
||||
// Decide whether we want an error or a warning.
|
||||
std::optional<decltype(diag::non_exhaustive_switch)> mainDiagType =
|
||||
diag::non_exhaustive_switch;
|
||||
bool downgrade = false;
|
||||
if (unknownCase) {
|
||||
switch (defaultReason) {
|
||||
case RequiresDefault::EmptySwitchBody:
|
||||
llvm_unreachable("there's an @unknown case; the body can't be empty");
|
||||
case RequiresDefault::No:
|
||||
if (!uncovered.isEmpty())
|
||||
mainDiagType = diag::non_exhaustive_switch_warn;
|
||||
downgrade = !uncovered.isEmpty();
|
||||
break;
|
||||
case RequiresDefault::UncoveredSwitch:
|
||||
case RequiresDefault::SpaceTooLarge: {
|
||||
@@ -1170,7 +1170,8 @@ namespace {
|
||||
theEnum->getParentModule()->isSystemModule();
|
||||
}
|
||||
DE.diagnose(startLoc, diag::non_exhaustive_switch_unknown_only,
|
||||
subjectType, shouldIncludeFutureVersionComment);
|
||||
subjectType, shouldIncludeFutureVersionComment)
|
||||
.warnUntilSwiftVersion(6);
|
||||
mainDiagType = std::nullopt;
|
||||
}
|
||||
break;
|
||||
@@ -1187,7 +1188,8 @@ namespace {
|
||||
return;
|
||||
case RequiresDefault::UncoveredSwitch: {
|
||||
OS << tok::kw_default << ":\n" << placeholder << "\n";
|
||||
DE.diagnose(startLoc, mainDiagType.value());
|
||||
DE.diagnose(startLoc, mainDiagType.value())
|
||||
.warnUntilSwiftVersionIf(downgrade, 6);
|
||||
DE.diagnose(startLoc, diag::missing_several_cases, /*default*/true)
|
||||
.fixItInsert(insertLoc, buffer.str());
|
||||
}
|
||||
@@ -1205,8 +1207,10 @@ namespace {
|
||||
if (uncovered.isEmpty()) return;
|
||||
|
||||
// Check if we still have to emit the main diagnostic.
|
||||
if (mainDiagType.has_value())
|
||||
DE.diagnose(startLoc, mainDiagType.value());
|
||||
if (mainDiagType.has_value()) {
|
||||
DE.diagnose(startLoc, mainDiagType.value())
|
||||
.warnUntilSwiftVersionIf(downgrade, 6);
|
||||
}
|
||||
|
||||
// Add notes to explain what's missing.
|
||||
auto processUncoveredSpaces =
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
// RUN: %target-swift-frontend -typecheck %s -Xcc -isystem -Xcc %S/Inputs/custom-modules -verify -enable-nonfrozen-enum-exhaustivity-diagnostics
|
||||
// RUN: %target-swift-frontend -typecheck %s -Xcc -isystem -Xcc %S/Inputs/custom-modules -verify -swift-version 5 -verify-additional-prefix swift5-
|
||||
// RUN: %target-swift-frontend -typecheck %s -Xcc -isystem -Xcc %S/Inputs/custom-modules -verify -swift-version 6 -verify-additional-prefix swift6-
|
||||
|
||||
import EnumExhaustivity
|
||||
|
||||
func test(_ value: RegularEnum, _ exhaustiveValue: ExhaustiveEnum) {
|
||||
switch value { // expected-warning {{switch covers known cases, but 'RegularEnum' may have additional unknown values, possibly added in future versions}} expected-note {{handle unknown values using "@unknown default"}}
|
||||
switch value {
|
||||
// expected-swift5-warning@-1 {{switch covers known cases, but 'RegularEnum' may have additional unknown values, possibly added in future versions}}
|
||||
// expected-swift6-error@-2 {{switch covers known cases, but 'RegularEnum' may have additional unknown values, possibly added in future versions}}
|
||||
// expected-note@-3 {{handle unknown values using "@unknown default"}}
|
||||
case .A: break
|
||||
case .B: break
|
||||
}
|
||||
@@ -29,7 +33,11 @@ func testAttributes(
|
||||
case .A, .B: break
|
||||
}
|
||||
|
||||
switch retetb { // expected-warning {{switch covers known cases, but 'RegularEnumTurnedExhaustiveThenBackViaAPINotes' may have additional unknown values, possibly added in future versions}} expected-note {{handle unknown values using "@unknown default"}}
|
||||
switch retetb {
|
||||
// expected-swift5-warning@-1 {{switch covers known cases, but 'RegularEnumTurnedExhaustiveThenBackViaAPINotes' may have additional unknown values, possibly added in future versions}}
|
||||
// expected-swift6-error@-2 {{switch covers known cases, but 'RegularEnumTurnedExhaustiveThenBackViaAPINotes' may have additional unknown values, possibly added in future versions}}
|
||||
// expected-note@-3 {{handle unknown values using "@unknown default"}}
|
||||
|
||||
case .A, .B: break
|
||||
}
|
||||
|
||||
|
||||
34
test/Compatibility/exhaustive_switch_swift_6.swift
Normal file
34
test/Compatibility/exhaustive_switch_swift_6.swift
Normal file
@@ -0,0 +1,34 @@
|
||||
// RUN: %target-typecheck-verify-swift -swift-version 6 -enable-library-evolution
|
||||
|
||||
enum OverlyLargeSpaceEnum {
|
||||
case case0
|
||||
case case1
|
||||
case case2
|
||||
case case3
|
||||
case case4
|
||||
case case5
|
||||
case case6
|
||||
case case7
|
||||
case case8
|
||||
case case9
|
||||
case case10
|
||||
case case11
|
||||
}
|
||||
|
||||
func testSwitch() -> Bool {
|
||||
switch (OverlyLargeSpaceEnum.case1, OverlyLargeSpaceEnum.case2) { // expected-error {{switch must be exhaustive}}
|
||||
// expected-note@-1 {{add missing case: '(.case11, _)'}}
|
||||
case (.case0, _): return true
|
||||
case (.case1, _): return true
|
||||
case (.case2, _): return true
|
||||
case (.case3, _): return true
|
||||
case (.case4, _): return true
|
||||
case (.case5, _): return true
|
||||
case (.case6, _): return true
|
||||
case (.case7, _): return true
|
||||
case (.case8, _): return true
|
||||
case (.case9, _): return true
|
||||
case (.case10, _): return true
|
||||
@unknown default: return false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user