[ConstraintSystem] Use missing conformance fix to diagnose contextual failures

Extend use of `missing protocol conformance` fix to cover contextual
failures, such as:

- Assignment mismatches, where destination requires source to conform
  to certain protocol (or protocol composition);
- Incorrect returns where returned type doesn't conform to the
  protocol specified in the signature.
This commit is contained in:
Pavel Yaskevich
2019-05-13 17:39:57 -07:00
parent ace86e81cf
commit ada6ab599a
6 changed files with 154 additions and 33 deletions

View File

@@ -2039,6 +2039,19 @@ bool ConstraintSystem::repairFailures(
return false;
};
auto repairByAddingConformance = [&](Type lhs, Type rhs) -> bool {
if (lhs->isTypeVariableOrMember())
return false;
if (rhs->isAny() ||
!(rhs->is<ProtocolType>() || rhs->is<ProtocolCompositionType>()))
return false;
conversionsOrFixes.push_back(MissingConformance::forContextual(
*this, lhs, rhs, getConstraintLocator(locator)));
return true;
};
if (path.empty()) {
if (!anchor)
return false;
@@ -2058,6 +2071,9 @@ bool ConstraintSystem::repairFailures(
if (repairByInsertingExplicitCall(lhs, rhs))
return true;
if (repairByAddingConformance(lhs, rhs))
return true;
if (isa<InOutExpr>(AE->getSrc())) {
conversionsOrFixes.push_back(
RemoveAddressOf::create(*this, getConstraintLocator(locator)));
@@ -2149,6 +2165,9 @@ bool ConstraintSystem::repairFailures(
if (repairByInsertingExplicitCall(lhs, rhs))
return true;
if (repairByAddingConformance(lhs, rhs))
return true;
// If both types are key path, the only differences
// between them are mutability and/or root, value type mismatch.
if (isKnownKeyPathType(lhs) && isKnownKeyPathType(rhs)) {
@@ -3352,9 +3371,9 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
return SolutionKind::Error;
}
auto *fix =
MissingConformance::create(*this, type, protocol->getDeclaredType(),
getConstraintLocator(locator));
auto *fix = MissingConformance::forRequirement(
*this, type, protocol->getDeclaredType(),
getConstraintLocator(locator));
if (!recordFix(fix))
return SolutionKind::Solved;
}
@@ -6588,6 +6607,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
case FixKind::InsertCall:
case FixKind::RemoveReturn:
case FixKind::AddConformance:
case FixKind::RemoveAddressOf:
case FixKind::SkipSameTypeRequirement:
case FixKind::SkipSuperclassRequirement:
@@ -6600,7 +6620,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
case FixKind::ExplicitlyEscaping:
case FixKind::CoerceToCheckedCast:
case FixKind::RelabelArguments:
case FixKind::AddConformance:
case FixKind::RemoveUnwrap:
case FixKind::DefineMemberBasedOnUse:
case FixKind::AllowTypeOrInstanceMember: