[ConstraintSystem] Avoid member lookup if base type is a "hole"

Member lookup on a "hole" is not going to produce any results
and it makes sense to detect early and short-circuit the constraint.
This commit is contained in:
Pavel Yaskevich
2019-12-04 14:23:12 -08:00
parent 805a5e9a1e
commit bbe0c098ba

View File

@@ -6060,20 +6060,33 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
auto locator = getConstraintLocator(locatorB); auto locator = getConstraintLocator(locatorB);
// If this is an unresolved member ref e.g. `.foo` and its contextual base // If the base type of this member lookup is a "hole" there is no
// type has been determined to be a "hole", let's mark the resulting member // reason to perform a lookup because it wouldn't return any results.
// type as a potential hole and continue solving. if (shouldAttemptFixes()) {
if (shouldAttemptFixes() && kind == ConstraintKind::UnresolvedValueMember && auto markMemberTypeAsPotentialHole = [&](Type memberTy) {
baseObjTy->getMetatypeInstanceType()->isHole()) { if (auto *typeVar = memberTy->getAs<TypeVariableType>())
auto *fix = recordPotentialHole(typeVar);
SpecifyBaseTypeForContextualMember::create(*this, member, locator); };
if (recordFix(fix))
return SolutionKind::Error;
if (auto *typeVar = memberTy->getAs<TypeVariableType>()) // If this is an unresolved member ref e.g. `.foo` and its contextual base
recordPotentialHole(typeVar); // type has been determined to be a "hole", let's mark the resulting member
// type as a potential hole and continue solving.
if (kind == ConstraintKind::UnresolvedValueMember &&
baseObjTy->getMetatypeInstanceType()->isHole()) {
auto *fix =
SpecifyBaseTypeForContextualMember::create(*this, member, locator);
if (recordFix(fix))
return SolutionKind::Error;
return SolutionKind::Solved; markMemberTypeAsPotentialHole(memberTy);
return SolutionKind::Solved;
} else if (kind == ConstraintKind::ValueMember && baseObjTy->isHole()) {
// If base type is a "hole" there is no reason to record any
// more "member not found" fixes for chained member references.
increaseScore(SK_Fix);
markMemberTypeAsPotentialHole(memberTy);
return SolutionKind::Solved;
}
} }
MemberLookupResult result = MemberLookupResult result =
@@ -6345,15 +6358,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
// fake its presence based on use, that makes it possible to diagnose // fake its presence based on use, that makes it possible to diagnose
// problems related to member lookup more precisely. // problems related to member lookup more precisely.
// If base type is a "hole" there is no reason to record any
// more "member not found" fixes for chained member references.
if (baseTy->isHole()) {
increaseScore(SK_Fix);
if (auto *memberTypeVar = memberTy->getAs<TypeVariableType>())
recordPotentialHole(memberTypeVar);
return SolutionKind::Solved;
}
return fixMissingMember(origBaseTy, memberTy, locator); return fixMissingMember(origBaseTy, memberTy, locator);
} }
return SolutionKind::Error; return SolutionKind::Error;