[Sema] Ensure performStmtDiagnostics is called for CaseStmts

Previously we would check if we have a SwitchStmt,
and apply diagnostics such as `checkExistentialTypes`
to the CaseStmts individually. This however would
have been missed for `catch` statements. The change
to consistently call `performStmtDiagnostics` in
closures fixed this for `do-catch`'s in closures,
this commit fixes it for those outside of closures.
Because this is source breaking, the existential
diagnostic is downgraded to a warning until Swift
7 for catch statements specifically.

While here, also apply the ambiguous where clause
diagnostic to `catch` statements.
This commit is contained in:
Hamish Knight
2024-11-12 18:26:54 +00:00
parent 964ba731bb
commit b644cd87a9
7 changed files with 244 additions and 57 deletions

View File

@@ -476,7 +476,7 @@ func r25178926(_ a : Type) {
switch a { // expected-error {{switch must be exhaustive}}
// expected-note@-1 {{missing case: '.Bar'}}
case .Foo, .Bar where 1 != 100:
// expected-warning @-1 {{'where' only applies to the second pattern match in this case}}
// expected-warning @-1 {{'where' only applies to the second pattern match in this 'case'}}
// expected-note @-2 {{disambiguate by adding a line break between them if this is desired}} {{14-14=\n }}
// expected-note @-3 {{duplicate the 'where' on both patterns to check both patterns}} {{12-12= where 1 != 100}}
break
@@ -504,6 +504,34 @@ func r25178926(_ a : Type) {
}
}
func testAmbiguousWhereInCatch() {
protocol P1 {}
protocol P2 {}
func throwingFn() throws {}
do {
try throwingFn()
} catch is P1, is P2 where .random() {
// expected-warning @-1 {{'where' only applies to the second pattern match in this 'catch'}}
// expected-note @-2 {{disambiguate by adding a line break between them if this is desired}} {{18-18=\n }}
// expected-note @-3 {{duplicate the 'where' on both patterns to check both patterns}} {{16-16= where .random()}}
} catch {
}
do {
try throwingFn()
} catch is P1,
is P2 where .random() {
} catch {
}
do {
try throwingFn()
} catch is P1 where .random(), is P2 where .random() {
} catch {
}
}
do {
guard 1 == 2 else {
break // expected-error {{unlabeled 'break' is only allowed inside a loop or switch, a labeled break is required to exit an if or do}}