@@ -6966,6 +6966,24 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
69666966
69676967 auto locator = getConstraintLocator (locatorB);
69686968
6969+ auto formUnsolved = [&](bool activate = false ) {
6970+ // If requested, generate a constraint.
6971+ if (flags.contains (TMF_GenerateConstraints)) {
6972+ auto *memberRef = Constraint::createMemberOrOuterDisjunction (
6973+ *this , kind, baseTy, memberTy, member, useDC, functionRefKind,
6974+ outerAlternatives, locator);
6975+
6976+ addUnsolvedConstraint (memberRef);
6977+
6978+ if (activate)
6979+ activateConstraint (memberRef);
6980+
6981+ return SolutionKind::Solved;
6982+ }
6983+
6984+ return SolutionKind::Unsolved;
6985+ };
6986+
69696987 // If the base type of this member lookup is a "hole" there is no
69706988 // reason to perform a lookup because it wouldn't return any results.
69716989 if (shouldAttemptFixes ()) {
@@ -6977,15 +6995,57 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
69776995 // If this is an unresolved member ref e.g. `.foo` and its contextual base
69786996 // type has been determined to be a "hole", let's mark the resulting member
69796997 // type as a potential hole and continue solving.
6980- if (kind == ConstraintKind::UnresolvedValueMember &&
6981- baseObjTy->getMetatypeInstanceType ()->isHole ()) {
6982- auto *fix =
6983- SpecifyBaseTypeForContextualMember::create (*this , member, locator);
6984- if (recordFix (fix))
6985- return SolutionKind::Error;
6998+ if (kind == ConstraintKind::UnresolvedValueMember) {
6999+ // Let's look through all metatypes to find "underlying" type
7000+ // of this lookup.
7001+ Type underlyingType = baseObjTy;
7002+ while (auto *MT = underlyingType->getAs <AnyMetatypeType>()) {
7003+ underlyingType = MT->getInstanceType ();
7004+ }
7005+
7006+ // Let's delay solving this constraint in diagnostic
7007+ // mode until it's certain that there is no way to
7008+ // find out what the base type is.
7009+ if (underlyingType->isTypeVariableOrMember ())
7010+ return formUnsolved ();
69867011
6987- markMemberTypeAsPotentialHole (memberTy);
6988- return SolutionKind::Solved;
7012+ // Let's record a fix only if the hole originates either
7013+ // at the result of the chain (that could happen since solving
7014+ // of this constraint is delayed until base could be resolved),
7015+ // or it is certain that base type can't be bound to any other
7016+ // type but a hole.
7017+ auto shouldRecordFixForHole = [&](HoleType *baseType) {
7018+ auto *originator =
7019+ baseType->getOriginatorType ().dyn_cast <TypeVariableType *>();
7020+
7021+ if (!originator)
7022+ return false ;
7023+
7024+ auto *originatorLoc = originator->getImpl ().getLocator ();
7025+
7026+ // It could either be a hole associated directly with the base
7027+ // or a hole which came from result type of the chain.
7028+ if (originatorLoc->isLastElement <
7029+ LocatorPathElt::UnresolvedMemberChainResult>()) {
7030+ auto *UMCR = castToExpr<UnresolvedMemberChainResultExpr>(
7031+ originatorLoc->getAnchor ());
7032+ return UMCR->getChainBase () == getAsExpr (locator->getAnchor ());
7033+ }
7034+
7035+ return originatorLoc == locator;
7036+ };
7037+
7038+ if (auto *hole = underlyingType->getAs <HoleType>()) {
7039+ if (shouldRecordFixForHole (hole)) {
7040+ auto *fix = SpecifyBaseTypeForContextualMember::create (*this , member,
7041+ locator);
7042+ if (recordFix (fix))
7043+ return SolutionKind::Error;
7044+ }
7045+
7046+ markMemberTypeAsPotentialHole (memberTy);
7047+ return SolutionKind::Solved;
7048+ }
69897049 } else if ((kind == ConstraintKind::ValueMember ||
69907050 kind == ConstraintKind::ValueWitness) &&
69917051 baseObjTy->getMetatypeInstanceType ()->isHole ()) {
@@ -7000,24 +7060,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
70007060 performMemberLookup (kind, member, baseTy, functionRefKind, locator,
70017061 /* includeInaccessibleMembers*/ shouldAttemptFixes ());
70027062
7003- auto formUnsolved = [&](bool activate = false ) {
7004- // If requested, generate a constraint.
7005- if (flags.contains (TMF_GenerateConstraints)) {
7006- auto *memberRef = Constraint::createMemberOrOuterDisjunction (
7007- *this , kind, baseTy, memberTy, member, useDC, functionRefKind,
7008- outerAlternatives, locator);
7009-
7010- addUnsolvedConstraint (memberRef);
7011-
7012- if (activate)
7013- activateConstraint (memberRef);
7014-
7015- return SolutionKind::Solved;
7016- }
7017-
7018- return SolutionKind::Unsolved;
7019- };
7020-
70217063 switch (result.OverallResult ) {
70227064 case MemberLookupResult::Unsolved:
70237065 return formUnsolved ();
0 commit comments