Sema: Allow resilient modules to add enum elements without breaking clients.

In the implementation of https://github.com/swiftlang/swift/pull/73472,
warnings about uncovered cases were upgraded to errors in switches covering
enums with an `@unknown default` case. This change was a mistake; it should not
be source breaking for a resilient library to add new cases to a non-frozen
enum.

Resolves rdar://138488976.
This commit is contained in:
Allan Shortlidge
2024-10-23 10:54:40 -07:00
parent 3e2556d0f6
commit 0ac8cd35d2
3 changed files with 37 additions and 6 deletions

View File

@@ -1188,7 +1188,7 @@ namespace {
case RequiresDefault::UncoveredSwitch: {
OS << tok::kw_default << ":\n" << placeholder << "\n";
DE.diagnose(startLoc, mainDiagType.value())
.warnUntilSwiftVersionIf(downgrade, 6);
.limitBehaviorIf(downgrade, DiagnosticBehavior::Warning);
DE.diagnose(startLoc, diag::missing_several_cases, /*default*/true)
.fixItInsert(insertLoc, buffer.str());
}
@@ -1208,7 +1208,7 @@ namespace {
// Check if we still have to emit the main diagnostic.
if (mainDiagType.has_value()) {
DE.diagnose(startLoc, mainDiagType.value())
.warnUntilSwiftVersionIf(downgrade, 6);
.limitBehaviorIf(downgrade, DiagnosticBehavior::Warning);
}
// Add notes to explain what's missing.

View File

@@ -29,6 +29,37 @@ func testSwitch() -> Bool {
case (.case8, _): return true
case (.case9, _): return true
case (.case10, _): return true
}
switch (OverlyLargeSpaceEnum.case1, OverlyLargeSpaceEnum.case2) { // expected-warning {{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
}
// No diagnostic
switch (OverlyLargeSpaceEnum.case1, OverlyLargeSpaceEnum.case2) {
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
case (.case11, _): return true
}
}

View File

@@ -219,14 +219,14 @@ public func testNonExhaustive(_ value: NonExhaustive, _ payload: NonExhaustivePa
}
switch value {
// expected-error@-1 {{switch must be exhaustive}}
// expected-warning@-1 {{switch must be exhaustive}}
// expected-note@-2 {{add missing case: '.b'}} {{+4:3-3=case .b:\n<#code#>\n}}
case .a: break
@unknown case _: break
}
switch value {
// expected-error@-1 {{switch must be exhaustive}}
// expected-warning@-1 {{switch must be exhaustive}}
// expected-note@-2 {{add missing case: '.a'}} {{+5:3-3=case .a:\n<#code#>\n}}
// expected-note@-3 {{add missing case: '.b'}} {{+5:3-3=case .b:\n<#code#>\n}}
// expected-note@-4 {{add missing cases}} {{+5:3-3=case .a:\n<#code#>\ncase .b:\n<#code#>\n}}
@@ -350,7 +350,7 @@ public func testNonExhaustive(_ value: NonExhaustive, _ payload: NonExhaustivePa
}
switch payload {
// expected-error@-1 {{switch must be exhaustive}}
// expected-warning@-1 {{switch must be exhaustive}}
// expected-note@-2 {{add missing case: '.b(_)'}} {{+4:3-3=case .b(_):\n<#code#>\n}}
case .a: break
@unknown case _: break
@@ -366,7 +366,7 @@ public func testNonExhaustive(_ value: NonExhaustive, _ payload: NonExhaustivePa
}
switch payload {
// expected-error@-1 {{switch must be exhaustive}}
// expected-warning@-1 {{switch must be exhaustive}}
// expected-note@-2 {{add missing case: '.b(true)'}} {{+5:3-3=case .b(true):\n<#code#>\n}}
case .a: break
case .b(false): break