Skip to content

Commit 4f2a175

Browse files
committed
[ConstraintSystem] Produce ambiguity notes based on the fix aggregate
It shouldn't matter how many fixes does the solution have overall, what matter is how many fixes are there for the location in question.
1 parent 4f034f0 commit 4f2a175

File tree

5 files changed

+17
-13
lines changed

5 files changed

+17
-13
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4674,10 +4674,16 @@ static bool diagnoseAmbiguity(
46744674
auto noteLoc =
46754675
decl->getLoc().isInvalid() ? getLoc(commonAnchor) : decl->getLoc();
46764676

4677-
if (solution.Fixes.size() == 1) {
4678-
diagnosed &=
4679-
solution.Fixes.front()->diagnose(solution, /*asNote*/ true);
4680-
} else if (llvm::all_of(solution.Fixes, [&](ConstraintFix *fix) {
4677+
SmallVector<const ConstraintFix *, 4> fixes;
4678+
for (const auto &entry : aggregateFix) {
4679+
if (entry.first == &solution)
4680+
fixes.push_back(entry.second);
4681+
}
4682+
4683+
if (fixes.size() == 1) {
4684+
diagnosed &= fixes.front()->diagnose(solution, /*asNote*/ true);
4685+
} else if (!fixes.empty() &&
4686+
llvm::all_of(fixes, [&](const ConstraintFix *fix) {
46814687
return fix->getLocator()
46824688
->findLast<LocatorPathElt::ApplyArgument>()
46834689
.has_value();
@@ -4691,8 +4697,7 @@ static bool diagnoseAmbiguity(
46914697
type->lookThroughAllOptionalTypes()->getAs<AnyFunctionType>();
46924698
assert(fn);
46934699

4694-
auto *argList =
4695-
solution.getArgumentList(solution.Fixes.front()->getLocator());
4700+
auto *argList = solution.getArgumentList(fixes.front()->getLocator());
46964701
assert(argList);
46974702

46984703
if (fn->getNumParams() == 1 && argList->isUnary()) {

test/Constraints/optional.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -592,8 +592,8 @@ do {
592592

593593
// Diagnose extraneous force unwrap in ambiguous context
594594
do {
595-
func test(_: Int) {} // expected-note {{found this candidate}}
596-
func test(_: String) {} // expected-note {{found this candidate}}
595+
func test(_: Int) {} // expected-note {{candidate expects value of type 'Int' for parameter #1 (got 'Double')}}
596+
func test(_: String) {} // expected-note {{candidate expects value of type 'String' for parameter #1 (got 'Double')}}
597597

598598
var x: Double = 42
599599
test(x!) // expected-error {{no exact matches in call to local function 'test'}}

test/Generics/function_defs.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,15 @@ protocol Subscriptable {
123123
func getIndex() -> Index
124124
func getValue() -> Value
125125

126-
subscript (index : Index) -> Value { get set } // expected-note {{found this candidate}}
126+
subscript (index : Index) -> Value { get set } // expected-note {{candidate expects value of type 'T.Index' for parameter #1 (got 'T.Value')}}
127127
}
128128

129129
protocol IntSubscriptable {
130130
associatedtype ElementType
131131

132132
func getElement() -> ElementType
133133

134-
subscript (index : Int) -> ElementType { get } // expected-note {{found this candidate}}
134+
subscript (index : Int) -> ElementType { get } // expected-note {{candidate expects value of type 'Int' for parameter #1 (got 'T.Value')}}
135135
}
136136

137137
func subscripting<T : Subscriptable & IntSubscriptable>(_ t: T) {

test/Sema/diag_ambiguous_overloads.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,8 @@ do {
148148
}
149149
}
150150
do {
151-
func f1(_ u: Int) -> String {} // expected-note {{found this candidate}} expected-note {{candidate expects value of type 'Int' for parameter #1 (got 'Double')}}
152-
func f1(_ u: String) -> Double {} // expected-note {{found this candidate}} expected-note {{candidate expects value of type 'String' for parameter #1 (got 'Double')}}
151+
func f1(_ u: Int) -> String {} // expected-note 2 {{candidate expects value of type 'Int' for parameter #1 (got 'Double')}}
152+
func f1(_ u: String) -> Double {} // expected-note 2 {{candidate expects value of type 'String' for parameter #1 (got 'Double')}}
153153
func f2(_ u: Int) {}
154154

155155
f2(f1(1 as Double)) // expected-error {{no exact matches in call to local function 'f1'}}

test/expr/expressions.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,7 +749,6 @@ func invalidDictionaryLiteral() {
749749

750750
[4].joined(separator: [1])
751751
// expected-error@-1 {{no exact matches in call to instance method 'joined'}}
752-
// expected-note@-2 {{found candidate with type '(String) -> String'}}
753752
// There is one more note here - candidate requires that 'Int' conform to 'Sequence' (requirement specified as 'Self.Element' : 'Sequence') pointing to Sequence extension
754753

755754
[4].joined(separator: [[[1]]])

0 commit comments

Comments
 (0)