Skip to content

Commit 6d85bd5

Browse files
[Sema] Handle coercion in ambiguity note emission
1 parent 5fee07b commit 6d85bd5

File tree

2 files changed

+44
-18
lines changed

2 files changed

+44
-18
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4687,10 +4687,25 @@ static bool diagnoseAmbiguity(
46874687
fixes.push_back(entry.second);
46884688
}
46894689

4690+
auto emitGeneralFoundCandidateNote = [&]() {
4691+
// Emit a general "found candidate" note
4692+
if (decl->getLoc().isInvalid()) {
4693+
if (candidateTypes.insert(type->getCanonicalType()).second)
4694+
DE.diagnose(getLoc(commonAnchor), diag::found_candidate_type, type);
4695+
} else {
4696+
DE.diagnose(noteLoc, diag::found_candidate);
4697+
}
4698+
};
4699+
46904700
if (fixes.size() == 1) {
46914701
diagnosed &= fixes.front()->diagnose(solution, /*asNote*/ true);
46924702
} else if (!fixes.empty() &&
46934703
llvm::all_of(fixes, [&](const ConstraintFix *fix) {
4704+
// Ignore coercion fixes in this context, to
4705+
// focus on the argument mismatches.
4706+
if (fix->getLocator()->isForCoercion())
4707+
return true;
4708+
46944709
return fix->getLocator()
46954710
->findLast<LocatorPathElt::ApplyArgument>()
46964711
.has_value();
@@ -4704,28 +4719,34 @@ static bool diagnoseAmbiguity(
47044719
type->lookThroughAllOptionalTypes()->getAs<AnyFunctionType>();
47054720
assert(fn);
47064721

4707-
auto *argList = solution.getArgumentList(fixes.front()->getLocator());
4708-
assert(argList);
4709-
4710-
if (fn->getNumParams() == 1 && argList->isUnary()) {
4711-
const auto &param = fn->getParams()[0];
4712-
auto argTy = solution.getResolvedType(argList->getUnaryExpr());
4722+
auto first = llvm::find_if(fixes, [&](const ConstraintFix *fix) {
4723+
return fix->getLocator()
4724+
->findLast<LocatorPathElt::ApplyArgument>()
4725+
.has_value();
4726+
});
47134727

4714-
DE.diagnose(noteLoc, diag::candidate_has_invalid_argument_at_position,
4715-
solution.simplifyType(param.getPlainType()),
4716-
/*position=*/1, param.isInOut(), argTy);
4728+
if (first != fixes.end()) {
4729+
auto *argList = solution.getArgumentList((*first)->getLocator());
4730+
assert(argList);
4731+
4732+
if (fn->getNumParams() == 1 && argList->isUnary()) {
4733+
const auto &param = fn->getParams()[0];
4734+
auto argTy = solution.getResolvedType(argList->getUnaryExpr());
4735+
4736+
DE.diagnose(noteLoc,
4737+
diag::candidate_has_invalid_argument_at_position,
4738+
solution.simplifyType(param.getPlainType()),
4739+
/*position=*/1, param.isInOut(), argTy);
4740+
} else {
4741+
DE.diagnose(noteLoc, diag::candidate_partial_match,
4742+
fn->getParamListAsString(fn->getParams()));
4743+
}
47174744
} else {
4718-
DE.diagnose(noteLoc, diag::candidate_partial_match,
4719-
fn->getParamListAsString(fn->getParams()));
4745+
// Only coercion ambiguity fixes.
4746+
emitGeneralFoundCandidateNote();
47204747
}
47214748
} else {
4722-
// Emit a general "found candidate" note
4723-
if (decl->getLoc().isInvalid()) {
4724-
if (candidateTypes.insert(type->getCanonicalType()).second)
4725-
DE.diagnose(getLoc(commonAnchor), diag::found_candidate_type, type);
4726-
} else {
4727-
DE.diagnose(noteLoc, diag::found_candidate);
4728-
}
4749+
emitGeneralFoundCandidateNote();
47294750
}
47304751
}
47314752

test/Constraints/overload.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,3 +324,8 @@ func f63834_D(_ x: Int = 0) {}
324324
func f63834_D(_ x: String) {}
325325

326326
(f63834_D as Magic)() // expected-error{{missing argument for parameter #1 in call}}
327+
328+
func fn63834_3() -> String {} // expected-note {{found candidate with type 'String'}}
329+
func fn63834_3() -> Double {} // expected-note {{found candidate with type 'Double'}}
330+
331+
fn63834_3() as Int // expected-error {{no exact matches in call to global function 'fn63834_3'}}

0 commit comments

Comments
 (0)