Merge pull request #29734 from LucianoPAlmeida/remove-diag-parameters-errors

[Diagnostics] Remove `FailureDiagnosis::diagnoseParameterErrors` from CSDiag
This commit is contained in:
Pavel Yaskevich
2020-02-11 01:32:31 -08:00
committed by GitHub
4 changed files with 68 additions and 88 deletions

View File

@@ -2765,6 +2765,9 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
ParameterList,
/// General ambiguity failure.
General,
/// Argument mismatch ambiguity where each solution has the same
/// argument mismatch fixes for the same call.
ArgumentMismatch
};
auto ambiguityKind = AmbiguityKind::CloseMatch;
@@ -2775,16 +2778,52 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
return false;
if (fixes.size() > 1) {
ambiguityKind = (ambiguityKind == AmbiguityKind::CloseMatch ||
ambiguityKind == AmbiguityKind::ParameterList) &&
// Attempt to disambiguite in cases where the argument matches
// involves tuple mismatches. e.g.
// func t<T, U>(_: (T, U), _: (U, T)) {}
// func useTuples(_ x: Int, y: Float) {
// t((x, y), (x, y))
// }
// So fixes are ambiguous in all solutions.
if ((ambiguityKind == AmbiguityKind::CloseMatch ||
ambiguityKind == AmbiguityKind::ArgumentMismatch) &&
llvm::all_of(fixes, [](const ConstraintFix *fix) -> bool {
auto *locator = fix->getLocator();
return locator->findLast<LocatorPathElt::ApplyArgument>().hasValue();
}) ? AmbiguityKind::ParameterList
: AmbiguityKind::General;
return fix->getKind() == FixKind::AllowTupleTypeMismatch;
})) {
ambiguityKind = AmbiguityKind::ArgumentMismatch;
} else {
ambiguityKind =
(ambiguityKind == AmbiguityKind::CloseMatch ||
ambiguityKind == AmbiguityKind::ArgumentMismatch ||
ambiguityKind == AmbiguityKind::ParameterList) &&
llvm::all_of(
fixes,
[](const ConstraintFix *fix) -> bool {
auto *locator = fix->getLocator();
return locator
->findLast<LocatorPathElt::ApplyArgument>()
.hasValue();
})
? AmbiguityKind::ParameterList
: AmbiguityKind::General;
}
}
for (const auto *fix: fixes) {
if (fixes.size() == 1) {
// Attempt to disambiguite in cases where all the solutions
// produces the same fixes for different generic arguments e.g.
// func f<T>(_: T, _: T) {}
// f(Int(1), Float(1))
//
ambiguityKind =
((ambiguityKind == AmbiguityKind::CloseMatch ||
ambiguityKind == AmbiguityKind::ArgumentMismatch) &&
fixes.front()->getKind() == FixKind::AllowArgumentTypeMismatch)
? AmbiguityKind::ArgumentMismatch
: AmbiguityKind::CloseMatch;
}
for (const auto *fix : fixes) {
auto *locator = fix->getLocator();
// Assignment failures are all about the source expression,
// because they treat destination as a contextual type.
@@ -2816,6 +2855,15 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
return true;
});
if (ambiguityKind == AmbiguityKind::ArgumentMismatch &&
viableSolutions.size() == 1) {
// Let's apply the solution so the contextual generic types
// are available in the system for diagnostics.
applySolution(*viableSolutions[0]);
solutions.front().Fixes.front()->diagnose(/*asNote*/ false);
return true;
}
if (!diagnosable || viableSolutions.size() < 2)
return false;
@@ -2860,6 +2908,7 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
};
switch (ambiguityKind) {
case AmbiguityKind::ArgumentMismatch:
case AmbiguityKind::CloseMatch:
// Handled below
break;