@@ -7322,7 +7322,7 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
73227322 // Dig out the instance type and figure out what members of the instance type
73237323 // we are going to see.
73247324 auto baseTy = candidate.getBaseType ();
7325- auto baseObjTy = baseTy->getRValueType ();
7325+ const auto baseObjTy = baseTy->getRValueType ();
73267326
73277327 bool hasInstanceMembers = false ;
73287328 bool hasInstanceMethods = false ;
@@ -7369,18 +7369,6 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
73697369 hasInstanceMethods = true ;
73707370 }
73717371
7372- // If our base is an existential type, we can't make use of any
7373- // member whose signature involves associated types.
7374- if (instanceTy->isExistentialType ()) {
7375- if (auto *proto = decl->getDeclContext ()->getSelfProtocolDecl ()) {
7376- if (!proto->isAvailableInExistential (decl)) {
7377- result.addUnviable (candidate,
7378- MemberLookupResult::UR_UnavailableInExistential);
7379- return ;
7380- }
7381- }
7382- }
7383-
73847372 // If the invocation's argument expression has a favored type,
73857373 // use that information to determine whether a specific overload for
73867374 // the candidate should be favored.
@@ -7400,6 +7388,20 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
74007388 }
74017389 }
74027390
7391+ const auto isUnsupportedExistentialMemberAccess = [&] {
7392+ // If our base is an existential type, we can't make use of any
7393+ // member whose signature involves associated types.
7394+ if (instanceTy->isExistentialType ()) {
7395+ if (auto *proto = decl->getDeclContext ()->getSelfProtocolDecl ()) {
7396+ if (!proto->isAvailableInExistential (decl)) {
7397+ return true ;
7398+ }
7399+ }
7400+ }
7401+
7402+ return false ;
7403+ };
7404+
74037405 // See if we have an instance method, instance member or static method,
74047406 // and check if it can be accessed on our base type.
74057407
@@ -7413,20 +7415,35 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
74137415 ? candidate
74147416 : OverloadChoice (instanceTy, decl,
74157417 FunctionRefKind::SingleApply);
7416- // If this is an instance member referenced from metatype
7417- // let's add unviable result to the set because it could be
7418- // either curried reference or an invalid call.
7419- //
7420- // New candidate shouldn't affect performance because such
7421- // choice would only be attempted when solver is in diagnostic mode.
7422- result.addUnviable (choice, MemberLookupResult::UR_InstanceMemberOnType);
7423-
7424- bool invalidMethodRef = isa<FuncDecl>(decl) && !hasInstanceMethods;
7425- bool invalidMemberRef = !isa<FuncDecl>(decl) && !hasInstanceMembers;
7426- // If this is definitely an invalid way to reference a method or member
7427- // on the metatype, let's stop here.
7428- if (invalidMethodRef || invalidMemberRef)
7418+
7419+ const bool invalidMethodRef = isa<FuncDecl>(decl) && !hasInstanceMethods;
7420+ const bool invalidMemberRef = !isa<FuncDecl>(decl) && !hasInstanceMembers;
7421+
7422+ if (invalidMethodRef || invalidMemberRef) {
7423+ // If this is definitely an invalid way to reference a method or member
7424+ // on the metatype, let's stop here.
7425+ result.addUnviable (choice,
7426+ MemberLookupResult::UR_InstanceMemberOnType);
7427+ return ;
7428+ } else if (isUnsupportedExistentialMemberAccess ()) {
7429+ // If the member reference itself is legal, but it turns out to be an
7430+ // unsupported existential member access, do not make further
7431+ // assumptions about the correctness of a potential call -- let
7432+ // the unsupported member access error prevail.
7433+ result.addUnviable (candidate,
7434+ MemberLookupResult::UR_UnavailableInExistential);
74297435 return ;
7436+ } else {
7437+ // Otherwise, still add an unviable result to the set, because it
7438+ // could be an invalid call that was supposed to be performed on an
7439+ // instance of the type.
7440+ //
7441+ // New candidate shouldn't affect performance because such
7442+ // choice would only be attempted when solver is in diagnostic mode.
7443+ result.addUnviable (choice,
7444+ MemberLookupResult::UR_InstanceMemberOnType);
7445+
7446+ }
74307447 }
74317448
74327449 // If the underlying type of a typealias is fully concrete, it is legal
@@ -7477,6 +7494,12 @@ performMemberLookup(ConstraintKind constraintKind, DeclNameRef memberName,
74777494 }
74787495 }
74797496
7497+ if (isUnsupportedExistentialMemberAccess ()) {
7498+ result.addUnviable (candidate,
7499+ MemberLookupResult::UR_UnavailableInExistential);
7500+ return ;
7501+ }
7502+
74807503 // If we have an rvalue base, make sure that the result isn't 'mutating'
74817504 // (only valid on lvalues).
74827505 if (!baseTy->is <AnyMetatypeType>() &&
0 commit comments