Skip to content

Commit dc6f86d

Browse files
committed
[CSRanking] Fix solution filtering not to erase everything when set is completely ambiguous
Since constraint solver has been improved to diagnose more problems via "fixes", sometimes applying fixes might lead to producing solutions which are completely ambiguous when compared to each other, and/or are incomparable, which leads to `findBestSolutions` erasing all of them while trying to compute best "partial" solution, which is incorrect. Resolves: rdar://problem/42678836
1 parent 7542f99 commit dc6f86d

File tree

5 files changed

+26
-7
lines changed

5 files changed

+26
-7
lines changed

lib/Sema/CSRanking.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1211,6 +1211,14 @@ ConstraintSystem::findBestSolution(SmallVectorImpl<Solution> &viable,
12111211
return bestIdx;
12121212
}
12131213

1214+
// If there is not a single "better" than others
1215+
// solution, which probably means that solutions
1216+
// were incomparable, let's just keep the original
1217+
// list instead of removing everything, even if we
1218+
// are asked to "minimize" the result.
1219+
if (losers.size() == viable.size())
1220+
return None;
1221+
12141222
// The comparison was ambiguous. Identify any solutions that are worse than
12151223
// any other solution.
12161224
for (unsigned i = 0, n = viable.size(); i != n; ++i) {

test/Constraints/patterns.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,10 +374,10 @@ func test8347() -> String {
374374
return ""
375375
}
376376

377-
func h() -> String {
377+
func h() -> String { // expected-note {{found this candidate}}
378378
return ""
379379
}
380-
func h() -> Double {
380+
func h() -> Double { // expected-note {{found this candidate}}
381381
return 3.0
382382
}
383383
func h() -> Int? { //expected-note{{found this candidate}}

test/Constraints/rdar42678836.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
func foo(chr: Character) -> String {
4+
return String(repeating: String(chr)) // expected-error {{argument labels '(repeating:)' do not match any available overloads}}
5+
// expected-note@-1 {{overloads for 'String' exist with these partially matching parameter lists}}
6+
}

test/expr/expressions.swift

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

551551
var pi_s: SpecialPi
552552

553-
func getPi() -> Float {} // expected-note 3 {{found this candidate}}
554-
func getPi() -> Double {} // expected-note 3 {{found this candidate}}
553+
func getPi() -> Float {}
554+
func getPi() -> Double {}
555555
func getPi() -> SpecialPi {}
556556

557557
enum Empty { }
@@ -573,12 +573,12 @@ func conversionTest(_ a: inout Double, b: inout Int) {
573573
var pi_d1 = Double(pi_d)
574574
var pi_s1 = SpecialPi(pi_s) // expected-error {{argument passed to call that takes no arguments}}
575575

576-
var pi_f2 = Float(getPi()) // expected-error {{ambiguous use of 'getPi()'}}
577-
var pi_d2 = Double(getPi()) // expected-error {{ambiguous use of 'getPi()'}}
576+
var pi_f2 = Float(getPi()) // expected-error {{ambiguous use of 'init'}}
577+
var pi_d2 = Double(getPi()) // expected-error {{ambiguous use of 'init'}}
578578
var pi_s2: SpecialPi = getPi() // no-warning
579579

580580
var float = Float.self
581-
var pi_f3 = float.init(getPi()) // expected-error {{ambiguous use of 'getPi()'}}
581+
var pi_f3 = float.init(getPi()) // expected-error {{ambiguous use of 'init'}}
582582
var pi_f4 = float.init(pi_f)
583583

584584
var e = Empty(f)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: %target-swift-ide-test -code-completion -code-completion-token=COMPLETE -source-filename=%s
2+
3+
public func * (lhs: Int, rhs: Character) -> String {
4+
return String(repeating: String(rhs), count #^COMPLETE^#: lhs)
5+
}

0 commit comments

Comments
 (0)