[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 a23bc3e189
commit 577e6291a6
6 changed files with 154 additions and 33 deletions

View File

@@ -2040,6 +2040,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;
@@ -2059,6 +2072,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)));
@@ -2150,6 +2166,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)) {
@@ -3347,9 +3366,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;
}
@@ -6585,6 +6604,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint(
case FixKind::InsertCall:
case FixKind::RemoveReturn:
case FixKind::AddConformance:
case FixKind::RemoveAddressOf:
case FixKind::SkipSameTypeRequirement:
case FixKind::SkipSuperclassRequirement:
@@ -6597,7 +6617,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: