mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CS] Avoid emitting invalid binding diagnostic in more cases
Also avoid emitting the diagnostic for an out of place binding pattern if there's an existing fix on a parent call expression, as that's the real source of the failure. rdar://113025351
This commit is contained in:
@@ -8365,12 +8365,13 @@ bool InvalidEmptyKeyPathFailure::diagnoseAsError() {
|
||||
}
|
||||
|
||||
bool InvalidPatternInExprFailure::diagnoseAsError() {
|
||||
// Check to see if we have something like 'case <fn>(let foo)', where <fn>
|
||||
// has a fix associated with it. In such a case, it's more likely than not
|
||||
// that the user is trying to write an EnumElementPattern, but has made some
|
||||
// kind of mistake in the function expr that causes it to be treated as an
|
||||
// ExprPattern. Emitting an additional error for the out of place 'let foo' is
|
||||
// just noise in that case, so let's avoid diagnosing.
|
||||
// Check to see if we have something like 'case <fn>(let foo)', where either
|
||||
// <fn> or the call itself has a fix associated with it. In such a case, it's
|
||||
// more likely than not that the user is trying to write an
|
||||
// EnumElementPattern, but has made some kind of mistake in the function expr
|
||||
// that causes it to be treated as an ExprPattern. Emitting an additional
|
||||
// error for the out of place 'let foo' is just noise in that case, so let's
|
||||
// avoid diagnosing.
|
||||
llvm::SmallPtrSet<Expr *, 4> fixAnchors;
|
||||
for (auto *fix : getSolution().Fixes) {
|
||||
if (auto *anchor = getAsExpr(fix->getAnchor()))
|
||||
@@ -8380,7 +8381,7 @@ bool InvalidPatternInExprFailure::diagnoseAsError() {
|
||||
auto *E = castToExpr(getLocator()->getAnchor());
|
||||
while (auto *parent = findParentExpr(E)) {
|
||||
if (auto *CE = dyn_cast<CallExpr>(parent)) {
|
||||
if (fixAnchors.contains(CE->getFn()))
|
||||
if (fixAnchors.contains(CE) || fixAnchors.contains(CE->getFn()))
|
||||
return false;
|
||||
}
|
||||
E = parent;
|
||||
|
||||
23
test/Constraints/rdar113025351.swift
Normal file
23
test/Constraints/rdar113025351.swift
Normal file
@@ -0,0 +1,23 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
struct S {
|
||||
enum E: Error {
|
||||
case e(Int)
|
||||
case f
|
||||
}
|
||||
}
|
||||
|
||||
func foo() throws {}
|
||||
|
||||
// rdar://113025351: Avoid emitting a separate diagnostic complaining that a
|
||||
// 'let' cannot be nested in an expression, as it just adds noise.
|
||||
func bar() throws {
|
||||
do {
|
||||
try foo()
|
||||
} catch S.E(let x) {} // expected-error {{'S.E' cannot be constructed because it has no accessible initializers}}
|
||||
}
|
||||
|
||||
func baz(_ x: S.E) {
|
||||
if case S.E(let y) = x {} // expected-error {{'S.E' cannot be constructed because it has no accessible initializers}}
|
||||
if case S.E(S.E.e(let y)) = x {} // expected-error {{'S.E' cannot be constructed because it has no accessible initializers}}
|
||||
}
|
||||
Reference in New Issue
Block a user