@@ -116,6 +116,31 @@ class ContainsSpecializableArchetype : public TypeWalker {
116
116
}
117
117
};
118
118
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
+ GenericSignature genericSig = ED->getGenericSignature ();
131
+ if (ED->getExtendedNominal () != PD) {
132
+ return false ;
133
+ }
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
+
119
144
static bool isExtensionAppliedInternal (const DeclContext *DC, Type BaseTy,
120
145
const ExtensionDecl *ED) {
121
146
// We can't do anything if the base type has unbound generic parameters.
@@ -131,6 +156,10 @@ static bool isExtensionAppliedInternal(const DeclContext *DC, Type BaseTy,
131
156
return true ;
132
157
133
158
GenericSignature genericSig = ED->getGenericSignature ();
159
+ if (isExtensionWithSelfBound (
160
+ ED, dyn_cast_or_null<ProtocolDecl>(BaseTy->getAnyNominal ()))) {
161
+ return true ;
162
+ }
134
163
auto *module = DC->getParentModule ();
135
164
SubstitutionMap substMap = BaseTy->getContextSubstitutionMap (
136
165
module , ED->getExtendedNominal ());
@@ -142,7 +171,10 @@ static bool isExtensionAppliedInternal(const DeclContext *DC, Type BaseTy,
142
171
143
172
static bool isMemberDeclAppliedInternal (const DeclContext *DC, Type BaseTy,
144
173
const ValueDecl *VD) {
145
- if (BaseTy->isExistentialType () && VD->isStatic ())
174
+ if (BaseTy->isExistentialType () && VD->isStatic () &&
175
+ !isExtensionWithSelfBound (
176
+ dyn_cast<ExtensionDecl>(VD->getDeclContext ()),
177
+ dyn_cast_or_null<ProtocolDecl>(BaseTy->getAnyNominal ())))
146
178
return false ;
147
179
148
180
// We can't leak type variables into another constraint system.
0 commit comments