@@ -116,6 +116,31 @@ class ContainsSpecializableArchetype : public TypeWalker {
116116 }
117117};
118118
119+ // / Returns `true` if `ED` is an extension of `PD` that binds `Self` to a
120+ // / concrete type, like `extension MyProto where Self == MyStruct {}`.
121+ // /
122+ // / In these cases, it is possible to access static members defined in the
123+ // / extension when perfoming unresolved member lookup in a type context of
124+ // / `PD`.
125+ static bool isExtensionWithSelfBound (const ExtensionDecl *ED,
126+ ProtocolDecl *PD) {
127+ if (!ED || !PD) {
128+ return false ;
129+ }
130+ if (ED->getExtendedNominal () != PD) {
131+ return false ;
132+ }
133+ GenericSignature genericSig = ED->getGenericSignature ();
134+ Type selfType = genericSig->getConcreteType (ED->getSelfInterfaceType ());
135+ if (!selfType) {
136+ return false ;
137+ }
138+ if (selfType->is <ExistentialType>()) {
139+ return false ;
140+ }
141+ return true ;
142+ }
143+
119144static bool isExtensionAppliedInternal (const DeclContext *DC, Type BaseTy,
120145 const ExtensionDecl *ED) {
121146 // We can't do anything if the base type has unbound generic parameters.
@@ -130,8 +155,20 @@ static bool isExtensionAppliedInternal(const DeclContext *DC, Type BaseTy,
130155 if (!ED->isConstrainedExtension ())
131156 return true ;
132157
133- GenericSignature genericSig = ED->getGenericSignature ();
158+ ProtocolDecl *BaseTypeProtocolDecl = nullptr ;
159+ if (auto opaqueType = dyn_cast<OpaqueTypeArchetypeType>(BaseTy)) {
160+ if (opaqueType->getConformsTo ().size () == 1 ) {
161+ BaseTypeProtocolDecl = opaqueType->getConformsTo ().front ();
162+ }
163+ } else {
164+ BaseTypeProtocolDecl = dyn_cast_or_null<ProtocolDecl>(BaseTy->getAnyNominal ());
165+ }
166+
167+ if (isExtensionWithSelfBound (ED, BaseTypeProtocolDecl)) {
168+ return true ;
169+ }
134170 auto *module = DC->getParentModule ();
171+ GenericSignature genericSig = ED->getGenericSignature ();
135172 SubstitutionMap substMap = BaseTy->getContextSubstitutionMap (
136173 module , ED->getExtendedNominal ());
137174 return checkRequirements (module ,
@@ -142,7 +179,10 @@ static bool isExtensionAppliedInternal(const DeclContext *DC, Type BaseTy,
142179
143180static bool isMemberDeclAppliedInternal (const DeclContext *DC, Type BaseTy,
144181 const ValueDecl *VD) {
145- if (BaseTy->isExistentialType () && VD->isStatic ())
182+ if (BaseTy->isExistentialType () && VD->isStatic () &&
183+ !isExtensionWithSelfBound (
184+ dyn_cast<ExtensionDecl>(VD->getDeclContext ()),
185+ dyn_cast_or_null<ProtocolDecl>(BaseTy->getAnyNominal ())))
146186 return false ;
147187
148188 // We can't leak type variables into another constraint system.
0 commit comments