mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[ConstraintSystem] Replace dependent member types with holes when the base type
doesn't conform to the associatedtype's protocol (only in diagnostic mode). This allows the solver to find solutions for more cases involving requirement failures for dependent member types without special cases across the solver that check for dependent member types with no type variables.
This commit is contained in:
@@ -2454,8 +2454,17 @@ Type ConstraintSystem::simplifyTypeImpl(Type type,
|
||||
auto *proto = assocType->getProtocol();
|
||||
auto conformance = DC->getParentModule()->lookupConformance(
|
||||
lookupBaseType, proto);
|
||||
if (!conformance)
|
||||
if (!conformance) {
|
||||
// If the base type doesn't conform to the associatedtype's protocol,
|
||||
// there will be a missing conformance fix applied in diagnostic mode,
|
||||
// so the concrete dependent member type is considered a "hole" in
|
||||
// order to continue solving.
|
||||
if (shouldAttemptFixes() &&
|
||||
getPhase() == ConstraintSystemPhase::Solving)
|
||||
return getASTContext().TheUnresolvedType;
|
||||
|
||||
return DependentMemberType::get(lookupBaseType, assocType);
|
||||
}
|
||||
|
||||
auto subs = SubstitutionMap::getProtocolSubstitutions(
|
||||
proto, lookupBaseType, conformance);
|
||||
@@ -2895,10 +2904,9 @@ static bool diagnoseConflictingGenericArguments(ConstraintSystem &cs,
|
||||
static bool
|
||||
diagnoseAmbiguityWithEphemeralPointers(ConstraintSystem &cs,
|
||||
ArrayRef<Solution> solutions) {
|
||||
bool allSolutionsHaveFixes = true;
|
||||
unsigned numSolutionsWithFixes = 0;
|
||||
for (const auto &solution : solutions) {
|
||||
if (solution.Fixes.empty()) {
|
||||
allSolutionsHaveFixes = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2906,11 +2914,14 @@ diagnoseAmbiguityWithEphemeralPointers(ConstraintSystem &cs,
|
||||
return fix->getKind() == FixKind::TreatEphemeralAsNonEphemeral;
|
||||
}))
|
||||
return false;
|
||||
|
||||
numSolutionsWithFixes += 1;
|
||||
}
|
||||
|
||||
// If all solutions have fixes for ephemeral pointers, let's
|
||||
// If all or no solutions have fixes for ephemeral pointers, let's
|
||||
// let `diagnoseAmbiguityWithFixes` diagnose the problem.
|
||||
if (allSolutionsHaveFixes)
|
||||
if (numSolutionsWithFixes == 0 ||
|
||||
numSolutionsWithFixes == solutions.size())
|
||||
return false;
|
||||
|
||||
// If only some of the solutions have ephemeral pointer fixes
|
||||
|
||||
Reference in New Issue
Block a user