mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[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:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user