@@ -336,50 +336,35 @@ void NormalProtocolConformance::setTypeWitness(
336
336
TypeWitnesses[assocType] = std::make_pair (substitution, typeDecl);
337
337
}
338
338
339
- // / TypeWitnesses is keyed by the protocol's own declarations, but
340
- // / DependentMemberTypes will sometimes store a base protocol's declaration.
341
- // / Map to the derived declaration if possible.
342
- static AssociatedTypeDecl *getOwnAssociatedTypeDecl (ProtocolDecl *protocol,
343
- AssociatedTypeDecl *assoc) {
344
- // Fast path.
345
- if (assoc->getProtocol () == protocol) return assoc;
346
-
347
- // Search the protocol.
348
- for (auto member : protocol->getMembers ()) {
349
- if (auto memberAssoc = dyn_cast<AssociatedTypeDecl>(member)) {
350
- if (memberAssoc->getName () == assoc->getName ()) {
351
- return memberAssoc;
352
- }
353
- }
354
- }
355
-
356
- // Just assume this is fine.
357
- return assoc;
358
- }
359
-
360
339
Type NormalProtocolConformance::getAssociatedType (Type assocType,
361
340
LazyResolver *resolver) const {
362
341
assert (assocType->isTypeParameter () &&
363
342
" associated type must be a type parameter" );
364
343
365
- // Fast path.
366
344
auto type = assocType->getCanonicalType ();
345
+ auto proto = getProtocol ();
346
+
347
+ #if false
348
+ // Fast path for generic parameters.
367
349
if (isa<GenericTypeParamType>(type)) {
368
- assert (type->isEqual (getProtocol () ->getSelfInterfaceType ()) &&
350
+ assert (type->isEqual (proto ->getSelfInterfaceType ()) &&
369
351
" type parameter in protocol was not Self" );
370
352
return getType ();
371
353
}
372
354
355
+ // Fast path for dependent member types on 'Self' of our associated types.
373
356
auto memberType = cast<DependentMemberType>(type);
357
+ if (memberType.getBase ()->isEqual (proto->getProtocolSelfType ()) &&
358
+ memberType->getAssocType ()->getProtocol () == proto)
359
+ return getTypeWitness (memberType->getAssocType (), nullptr ).getReplacement ();
360
+ #endif
374
361
375
- // TODO: make this handle multiple levels of dependent member type.
376
- assert (memberType.getBase ()->isEqual (getProtocol ()->getSelfInterfaceType ()) &&
377
- " dependent member in protocol was not rooted in Self" );
378
-
379
- auto assocTypeDecl =
380
- getOwnAssociatedTypeDecl (getProtocol (), memberType->getAssocType ());
381
- auto &subst = getTypeWitnessSubstAndDecl (assocTypeDecl, resolver).first ;
382
- return subst.getReplacement ();
362
+ // General case: consult the substitution map.
363
+ auto self = const_cast <NormalProtocolConformance *>(this );
364
+ auto substMap =
365
+ SubstitutionMap::getProtocolSubstitutions (proto, getType (),
366
+ ProtocolConformanceRef (self));
367
+ return type.subst (substMap);
383
368
}
384
369
385
370
ProtocolConformanceRef
@@ -389,48 +374,21 @@ NormalProtocolConformance::getAssociatedConformance(Type assocType,
389
374
assert (assocType->isTypeParameter () &&
390
375
" associated type must be a type parameter" );
391
376
392
- #ifndef NDEBUG
393
- bool foundInRequirements = false ;
377
+ unsigned conformanceIndex = 0 ;
394
378
for (auto &reqt :
395
379
getProtocol ()->getRequirementSignature ()->getRequirements ()) {
396
- if (reqt.getKind () == RequirementKind::Conformance &&
397
- reqt.getFirstType ()->isEqual (assocType) &&
398
- reqt.getSecondType ()->castTo <ProtocolType>()->getDecl () == protocol) {
399
- foundInRequirements = true ;
400
- break ;
401
- }
402
- }
403
- assert (foundInRequirements &&
404
- " requested conformance was not a direct requirement of the protocol" );
405
- #endif
406
-
407
- auto type = assocType->getCanonicalType ();
380
+ if (reqt.getKind () == RequirementKind::Conformance) {
381
+ // Is this the conformance we're looking for?
382
+ if (reqt.getFirstType ()->isEqual (assocType) &&
383
+ reqt.getSecondType ()->castTo <ProtocolType>()->getDecl () == protocol)
384
+ return getSignatureConformances ()[conformanceIndex];
408
385
409
- if (isa<GenericTypeParamType>(type)) {
410
- assert (type->isEqual (getProtocol ()->getSelfInterfaceType ()) &&
411
- " type parameter in protocol was not Self" );
412
- auto conf = getInheritedConformance (protocol);
413
- assert (conf && " inherited conformances cannot be abstract" );
414
- return ProtocolConformanceRef (conf);
386
+ ++conformanceIndex;
387
+ }
415
388
}
416
389
417
- auto memberType = cast<DependentMemberType>(type);
418
-
419
- // For now, NormalProtocolConformance does not store indirect associations.
420
- assert (memberType.getBase ()->isEqual (getProtocol ()->getSelfInterfaceType ()) &&
421
- " dependent member in protocol was not rooted in Self" );
422
-
423
- auto assocTypeDecl =
424
- getOwnAssociatedTypeDecl (getProtocol (), memberType->getAssocType ());
425
- auto &subst = getTypeWitnessSubstAndDecl (assocTypeDecl, resolver).first ;
426
-
427
- // Scan the conformances for the exact conformance.
428
- // TODO: should we allow indirect conformances for convenience of use?
429
- for (auto &conf : subst.getConformances ()) {
430
- if (conf.getRequirement () == protocol)
431
- return conf;
432
- }
433
- llvm_unreachable (" missing conformance to protocol" );
390
+ llvm_unreachable (
391
+ " requested conformance was not a direct requirement of the protocol" );
434
392
}
435
393
436
394
// / Retrieve the value witness corresponding to the given requirement.
0 commit comments