Skip to content

Commit 5011300

Browse files
Merge pull request #39220 from LucianoPAlmeida/SR-15053-overload-diags
[Sema][SR-15053] Ignore ambiguity from conformance in some situations
2 parents d62bf7d + ada9bfb commit 5011300

File tree

5 files changed

+37
-9
lines changed

5 files changed

+37
-9
lines changed

include/swift/AST/Expr.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,15 @@
1919

2020
#include "swift/AST/ArgumentList.h"
2121
#include "swift/AST/Attr.h"
22+
#include "swift/AST/Availability.h"
2223
#include "swift/AST/CaptureInfo.h"
2324
#include "swift/AST/ConcreteDeclRef.h"
25+
#include "swift/AST/Decl.h"
2426
#include "swift/AST/DeclContext.h"
2527
#include "swift/AST/DeclNameLoc.h"
2628
#include "swift/AST/FunctionRefKind.h"
2729
#include "swift/AST/ProtocolConformanceRef.h"
2830
#include "swift/AST/TypeAlignments.h"
29-
#include "swift/AST/Availability.h"
3031
#include "swift/Basic/Debug.h"
3132
#include "swift/Basic/InlineBitfield.h"
3233
#include "llvm/Support/TrailingObjects.h"
@@ -1453,6 +1454,8 @@ class OverloadedDeclRefExpr final : public OverloadSetRefExpr {
14531454
SourceLoc getLoc() const { return Loc.getBaseNameLoc(); }
14541455
SourceRange getSourceRange() const { return Loc.getSourceRange(); }
14551456

1457+
bool isForOperator() const { return getDecls().front()->isOperator(); }
1458+
14561459
static bool classof(const Expr *E) {
14571460
return E->getKind() == ExprKind::OverloadedDeclRef;
14581461
}

include/swift/Sema/ConstraintLocator.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1106,6 +1106,14 @@ class ConstraintLocatorBuilder {
11061106
return false;
11071107
}
11081108

1109+
bool isForRequirement(RequirementKind kind) const {
1110+
if (auto lastElt = last()) {
1111+
auto requirement = lastElt->getAs<LocatorPathElt::AnyRequirement>();
1112+
return requirement && kind == requirement->getRequirementKind();
1113+
}
1114+
return false;
1115+
}
1116+
11091117
/// Checks whether this locator is describing an argument application for a
11101118
/// non-ephemeral parameter.
11111119
bool isNonEphemeralParameterApplication() const {

lib/Sema/CSSimplify.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,18 @@ assessRequirementFailureImpact(ConstraintSystem &cs, Type requirementType,
18641864
if (!cs.findSelectedOverloadFor(calleeLoc))
18651865
return 10;
18661866
}
1867+
1868+
auto resolvedTy = cs.simplifyType(requirementType);
1869+
1870+
// Increase the impact of a conformance fix for generic parameters on
1871+
// operators where such conformance failures are not as important as argument
1872+
// mismatches or contextual failures.
1873+
if (auto *ODRE = getAsExpr<OverloadedDeclRefExpr>(anchor)) {
1874+
if (locator.isForRequirement(RequirementKind::Conformance) &&
1875+
resolvedTy->is<ArchetypeType>() && ODRE->isForOperator()) {
1876+
++impact;
1877+
}
1878+
}
18671879

18681880
// Increase the impact of a conformance fix for a standard library
18691881
// or foundation type, as it's unlikely to be a good suggestion.
@@ -1876,16 +1888,11 @@ assessRequirementFailureImpact(ConstraintSystem &cs, Type requirementType,
18761888
// rdar://60727310. Once we better handle the separation of conformance fixes
18771889
// from argument mismatches in cases like SR-12438, we should be able to
18781890
// remove it from the condition.
1879-
auto resolvedTy = cs.simplifyType(requirementType);
18801891
if ((requirementType->is<TypeVariableType>() && resolvedTy->isStdlibType()) ||
18811892
resolvedTy->isAny() || resolvedTy->isAnyObject() ||
18821893
getKnownFoundationEntity(resolvedTy->getString())) {
1883-
if (auto last = locator.last()) {
1884-
if (auto requirement = last->getAs<LocatorPathElt::AnyRequirement>()) {
1885-
auto kind = requirement->getRequirementKind();
1886-
if (kind == RequirementKind::Conformance)
1887-
impact += 2;
1888-
}
1894+
if (locator.isForRequirement(RequirementKind::Conformance)) {
1895+
impact += 2;
18891896
}
18901897
}
18911898

test/Constraints/diag_ambiguities.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,13 @@ class MoviesViewController {
6868
_ = itemType // expected-error {{ambiguous use of 'itemType'}}
6969
}
7070
}
71+
72+
// SR-15053
73+
func SR15053<T : Numeric>(_ a: T, _ b: T) -> T {
74+
(a + b) / 2 // expected-error{{cannot convert return expression of type 'Int' to return type 'T'}}
75+
// expected-error@-1{{cannot convert value of type 'T' to expected argument type 'Int'}}
76+
}
77+
78+
func SR15053<T : Numeric>(_ a: T, _ b: T) {
79+
(a + b) / 2 // expected-error{{cannot convert value of type 'T' to expected argument type 'Int'}}
80+
}

test/Constraints/rdar40002266.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ import Foundation
66
struct S {
77
init<T: NSNumber>(_ num: T) { // expected-note {{where 'T' = 'Bool'}}
88
self.init(num != 0) // expected-error {{initializer 'init(_:)' requires that 'Bool' inherit from 'NSNumber'}}
9-
// expected-error@-1 {{referencing operator function '!=' on 'BinaryInteger' requires that 'T' conform to 'BinaryInteger'}}
9+
// expected-error@-1 {{cannot convert value of type 'T' to expected argument type 'Int'}}
1010
}
1111
}

0 commit comments

Comments
 (0)