19
19
20
20
#include " swift/AST/Decl.h"
21
21
#include " swift/AST/GenericSignature.h"
22
+ #include " swift/AST/NameLookupRequests.h"
22
23
#include " swift/AST/ProtocolConformance.h"
23
24
#include " swift/AST/SubstitutionMap.h"
24
25
#include " swift/AST/TypeMatcher.h"
@@ -216,10 +217,12 @@ AssociatedTypeInference::inferTypeWitnessesViaValueWitnesses(
216
217
// Retrieve the generic signature of the extension.
217
218
const auto extensionSig = extension->getGenericSignature ();
218
219
220
+ auto *proto = dyn_cast<ProtocolDecl>(extendedNominal);
221
+
219
222
// If the extension is bound to the nominal the conformance is
220
223
// declared on, it is viable for inference when its conditional
221
224
// requirements are satisfied by those of the conformance context.
222
- if (!isa<ProtocolDecl>(extendedNominal) ) {
225
+ if (!proto ) {
223
226
// Extensions of non-generic nominals are always viable for inference.
224
227
if (!extensionSig)
225
228
return true ;
@@ -235,21 +238,23 @@ AssociatedTypeInference::inferTypeWitnessesViaValueWitnesses(
235
238
// in the first place. Only check conformances on the `Self` type,
236
239
// because those have to be explicitly declared on the type somewhere
237
240
// so won't be affected by whatever answer inference comes up with.
238
- auto selfTy = extension->getSelfInterfaceType ();
239
- for (const Requirement &reqt : extensionSig->getRequirements ()) {
240
- switch (reqt.getKind ()) {
241
- case RequirementKind::Conformance:
242
- case RequirementKind::Superclass:
243
- // FIXME: This is the wrong check
244
- if (selfTy->isEqual (reqt.getFirstType ()) &&
245
- !TypeChecker::isSubtypeOf (conformance->getType (),
246
- reqt.getSecondType (), dc))
247
- return false ;
248
- break ;
241
+ auto *module = dc->getParentModule ();
242
+ auto checkConformance = [&](ProtocolDecl *proto) {
243
+ auto otherConf = module ->lookupConformance (conformance->getType (),
244
+ proto);
245
+ return (otherConf && otherConf.getConditionalRequirements ().empty ());
246
+ };
249
247
250
- case RequirementKind::Layout:
251
- case RequirementKind::SameType:
252
- break ;
248
+ // First check the extended protocol itself.
249
+ if (!checkConformance (proto))
250
+ return false ;
251
+
252
+ // Now check any additional bounds on 'Self' from the where clause.
253
+ auto bounds = getSelfBoundsFromWhereClause (extension);
254
+ for (auto *decl : bounds.decls ) {
255
+ if (auto *proto = dyn_cast<ProtocolDecl>(decl)) {
256
+ if (!checkConformance (proto))
257
+ return false ;
253
258
}
254
259
}
255
260
0 commit comments