From ecf814693819680911db46599ce1b51cc7446a0c Mon Sep 17 00:00:00 2001 From: Pavel Yaskevich Date: Thu, 29 Aug 2019 15:27:29 -0700 Subject: [PATCH] [Diagnostics] Treat type requirement failures associated with `Self` = `Any` as unrelated This helps us to filter out cases like operator overloads where `Self` type comes from e.g. default for collection element - `[1, "hello"].map { $0 + 1 }`. Main problem here is that collection type couldn't be determined without unification to `Any` and `+` failing for all numeric overloads is just a consequence. --- lib/Sema/CSSimplify.cpp | 19 ++++++++++++++++++- test/Constraints/closures.swift | 3 +-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index d9fbb390c33..d075cba5318 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -3832,8 +3832,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint( ConstraintKind kind, ConstraintLocatorBuilder locator, TypeMatchOptions flags) { + auto *typeVar = type->getAs(); if (shouldAttemptFixes()) { - auto *typeVar = type->getAs(); // If type variable, associated with this conformance check, // has been determined to be a "hole" in constraint system, // let's consider this check a success without recording @@ -3983,6 +3983,23 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint( return SolutionKind::Error; if (path.back().is()) { + // If this is a requirement associated with `Self` which is bound + // to `Any`, let's consider this "too incorrect" to continue. + // + // This helps us to filter out cases like operator overloads where + // `Self` type comes from e.g. default for collection element - + // `[1, "hello"].map { $0 + 1 }`. Main problem here is that + // collection type couldn't be determined without unification to + // `Any` and `+` failing for all numeric overloads is just a consequence. + if (typeVar && type->isAny()) { + auto *GP = typeVar->getImpl().getGenericParameter(); + if (auto *GPD = GP->getDecl()) { + auto *DC = GPD->getDeclContext(); + if (DC->isTypeContext() && DC->getSelfInterfaceType()->isEqual(GP)) + return SolutionKind::Error; + } + } + if (auto *fix = fixRequirementFailure(*this, type, protocolTy, anchor, path)) { if (!recordFix(fix)) { diff --git a/test/Constraints/closures.swift b/test/Constraints/closures.swift index 389ad93b178..9530c3c1ce3 100644 --- a/test/Constraints/closures.swift +++ b/test/Constraints/closures.swift @@ -182,8 +182,7 @@ func r22162441(_ lines: [String]) { func testMap() { let a = 42 - [1,a].map { $0 + 1.0 } // expected-error {{binary operator '+' cannot be applied to operands of type 'Any' and 'Double'}} - // expected-note @-1 {{expected an argument list of type '(Double, Double)'}} + [1,a].map { $0 + 1.0 } // expected-error {{cannot convert value of type 'Int' to expected element type 'Double'}} } // "UnresolvedDot" "in wrong phase" assertion from verifier