Skip to content

Commit 566e00c

Browse files
authored
Merge pull request #59305 from xedin/rdar-94360230
[ConstraintSystem] Use '# of overloads' as a tie-breaker in ambiguities
2 parents a38fc3d + 8f69b9f commit 566e00c

File tree

3 files changed

+32
-11
lines changed

3 files changed

+32
-11
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4711,15 +4711,15 @@ bool ConstraintSystem::diagnoseAmbiguity(ArrayRef<Solution> solutions) {
47114711
// overloads, depth, *reverse* of the index). N.B. - cannot be used for the
47124712
// reversing: the score version of index == 0 should be > than that of 1, but
47134713
// -0 == 0 < UINT_MAX == -1, whereas ~0 == UINT_MAX > UINT_MAX - 1 == ~1.
4714-
auto score = [](unsigned distinctOverloads, unsigned depth, unsigned index) {
4715-
return std::make_tuple(distinctOverloads, depth, ~index);
4714+
auto score = [](unsigned depth, unsigned index, unsigned distinctOverloads) {
4715+
return std::make_tuple(depth, ~index, distinctOverloads);
47164716
};
4717-
auto bestScore = score(0, 0, std::numeric_limits<unsigned>::max());
4717+
auto bestScore = score(0, std::numeric_limits<unsigned>::max(), 0);
47184718

47194719
// Get a map of expressions to their depths and post-order traversal indices.
47204720
// Heuristically, all other things being equal, we should complain about the
4721-
// ambiguous expression that (1) has the most overloads, (2) is deepest, or
4722-
// (3) comes earliest in the expression.
4721+
// ambiguous expression that (1) is deepest, (2) comes earliest in the
4722+
// expression, or (3) has the most overloads.
47234723
llvm::DenseMap<Expr *, unsigned> indexMap;
47244724
for (auto expr : InputExprs) {
47254725
extendPreorderIndexMap(expr, indexMap);
@@ -4780,7 +4780,7 @@ bool ConstraintSystem::diagnoseAmbiguity(ArrayRef<Solution> solutions) {
47804780

47814781
// If we have more distinct overload choices for this locator than for
47824782
// prior locators, just keep this locator.
4783-
auto thisScore = score(distinctOverloads, depth, index);
4783+
auto thisScore = score(depth, index, distinctOverloads);
47844784
if (thisScore > bestScore) {
47854785
bestScore = thisScore;
47864786
bestOverload = i;

test/Constraints/diag_ambiguities.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,24 @@ func %% (_ lhs: Float, _ rhs: Float) -> Float {
8888
func SR15053<T : Numeric>(_ a: T, _ b: T) {
8989
(a + b) %% 2 // expected-error {{cannot convert value of type 'T' to expected argument type 'Int'}}
9090
}
91+
92+
// rdar://94360230 - diagnosing 'filter' instead of ambiguity in its body
93+
func test_diagnose_deepest_ambiguity() {
94+
struct S {
95+
func ambiguous(_: Int = 0) -> Bool { true } // expected-note 2 {{found this candidate}}
96+
func ambiguous(_: String = "") -> Bool { true } // expected-note 2 {{found this candidate}}
97+
}
98+
99+
func test_single(arr: [S]) {
100+
arr.filter { $0.ambiguous() } // expected-error {{ambiguous use of 'ambiguous'}}
101+
}
102+
103+
func test_multi(arr: [S]) {
104+
arr.filter {
105+
if true {
106+
print($0.ambiguous()) // expected-error {{ambiguous use of 'ambiguous'}}
107+
}
108+
return true
109+
}
110+
}
111+
}

test/expr/expressions.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -562,8 +562,8 @@ struct SpecialPi {} // Type with no implicit construction.
562562

563563
var pi_s: SpecialPi
564564

565-
func getPi() -> Float {}
566-
func getPi() -> Double {}
565+
func getPi() -> Float {} // expected-note 3 {{found this candidate}}
566+
func getPi() -> Double {} // expected-note 3 {{found this candidate}}
567567
func getPi() -> SpecialPi {}
568568

569569
enum Empty { }
@@ -585,12 +585,12 @@ func conversionTest(_ a: inout Double, b: inout Int) {
585585
var pi_d1 = Double(pi_d)
586586
var pi_s1 = SpecialPi(pi_s) // expected-error {{argument passed to call that takes no arguments}}
587587

588-
var pi_f2 = Float(getPi()) // expected-error {{ambiguous use of 'init(_:)'}}
589-
var pi_d2 = Double(getPi()) // expected-error {{ambiguous use of 'init(_:)'}}
588+
var pi_f2 = Float(getPi()) // expected-error {{ambiguous use of 'getPi()'}}
589+
var pi_d2 = Double(getPi()) // expected-error {{ambiguous use of 'getPi()'}}
590590
var pi_s2: SpecialPi = getPi() // no-warning
591591

592592
var float = Float.self
593-
var pi_f3 = float.init(getPi()) // expected-error {{ambiguous use of 'init(_:)'}}
593+
var pi_f3 = float.init(getPi()) // expected-error {{ambiguous use of 'getPi()'}}
594594
var pi_f4 = float.init(pi_f)
595595

596596
var e = Empty(f) // expected-warning {{variable 'e' inferred to have type 'Empty', which is an enum with no cases}} expected-note {{add an explicit type annotation to silence this warning}} {{8-8=: Empty}}

0 commit comments

Comments
 (0)