@@ -6966,6 +6966,24 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
6966
6966
6967
6967
auto locator = getConstraintLocator (locatorB);
6968
6968
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
+
6969
6987
// If the base type of this member lookup is a "hole" there is no
6970
6988
// reason to perform a lookup because it wouldn't return any results.
6971
6989
if (shouldAttemptFixes ()) {
@@ -6977,15 +6995,57 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
6977
6995
// If this is an unresolved member ref e.g. `.foo` and its contextual base
6978
6996
// type has been determined to be a "hole", let's mark the resulting member
6979
6997
// 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 ();
6986
7011
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
+ }
6989
7049
} else if ((kind == ConstraintKind::ValueMember ||
6990
7050
kind == ConstraintKind::ValueWitness) &&
6991
7051
baseObjTy->getMetatypeInstanceType ()->isHole ()) {
@@ -7000,24 +7060,6 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
7000
7060
performMemberLookup (kind, member, baseTy, functionRefKind, locator,
7001
7061
/* includeInaccessibleMembers*/ shouldAttemptFixes ());
7002
7062
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
-
7021
7063
switch (result.OverallResult ) {
7022
7064
case MemberLookupResult::Unsolved:
7023
7065
return formUnsolved ();
0 commit comments