@@ -468,69 +468,65 @@ ProtocolConformance *ProtocolConformance::subst(Module *module,
468
468
469
469
ProtocolConformance *
470
470
ProtocolConformance::getInheritedConformance (ProtocolDecl *protocol) const {
471
- // Preserve specialization through this operation by peeling off the
472
- // substitutions from a specialized conformance so we can apply them later.
473
- const ProtocolConformance *unspecialized;
474
- SubstitutionIterator subs;
471
+ auto &C = getProtocol ()->getASTContext ();
472
+ // Preserve specialization and class inheritance through this operation by
473
+ // reapplying them to the conformance we find.
475
474
switch (getKind ()) {
476
475
case ProtocolConformanceKind::Specialized: {
477
476
auto spec = cast<SpecializedProtocolConformance>(this );
478
- unspecialized = spec->getGenericConformance ();
479
- subs = spec->getGenericSubstitutionIterator ();
480
- break ;
477
+ auto inherited = spec->getGenericConformance ()
478
+ ->getInheritedConformance (protocol);
479
+ assert (inherited->getType ()->isEqual (spec->getGenericConformance ()->getType ())
480
+ && " inherited conformance doesn't match type?!" );
481
+
482
+ TypeSubstitutionMap subMap;
483
+ ArchetypeConformanceMap conformanceMap;
484
+
485
+ // Fill in the substitution and conformance maps.
486
+ for (auto archAndSub : spec->getGenericSubstitutionIterator ()) {
487
+ auto arch = archAndSub.first ;
488
+ auto sub = archAndSub.second ;
489
+ conformanceMap[arch] = sub.getConformances ();
490
+ if (arch->isPrimary ())
491
+ subMap[arch] = sub.getReplacement ();
492
+ }
493
+ auto r = inherited->subst (getDeclContext ()->getParentModule (),
494
+ getType (), spec->getGenericSubstitutions (),
495
+ subMap, conformanceMap);
496
+ assert (getType ()->isEqual (r->getType ())
497
+ && " substitution didn't produce conformance for same type?!" );
498
+ return r;
481
499
}
482
500
501
+ case ProtocolConformanceKind::Inherited: {
502
+ auto classInherited = cast<InheritedProtocolConformance>(this );
503
+ auto protoInherited = classInherited->getInheritedConformance ()
504
+ ->getInheritedConformance (protocol);
505
+ assert (protoInherited->getType ()->isEqual (
506
+ classInherited->getInheritedConformance ()->getType ())
507
+ && " inherited conformance doesn't match type?!" );
508
+ return C.getInheritedConformance (classInherited->getType (),
509
+ protoInherited);
510
+ }
511
+
483
512
case ProtocolConformanceKind::Normal:
484
- case ProtocolConformanceKind::Inherited:
485
- unspecialized = this ;
513
+ // For a normal conformance, do the inheritance lookup.
486
514
break ;
487
515
}
488
516
489
-
490
- ProtocolConformance *foundInherited;
491
-
492
517
// Search for the inherited conformance among our immediate parents.
493
- auto &inherited = unspecialized-> getInheritedConformances ();
518
+ auto &inherited = getInheritedConformances ();
494
519
auto known = inherited.find (protocol);
495
- if (known != inherited.end ()) {
496
- foundInherited = known->second ;
497
- goto found_inherited;
498
- }
520
+ if (known != inherited.end ())
521
+ return known->second ;
499
522
500
523
// If not there, the inherited conformance must be available through one of
501
524
// our parents.
502
525
for (auto &inheritedMapping : inherited)
503
- if (inheritedMapping.first ->inheritsFrom (protocol)) {
504
- foundInherited = inheritedMapping.second ->
505
- getInheritedConformance (protocol);
506
- goto found_inherited;
507
- }
526
+ if (inheritedMapping.first ->inheritsFrom (protocol))
527
+ return inheritedMapping.second ->getInheritedConformance (protocol);
508
528
509
529
llvm_unreachable (" Can't find the inherited conformance." );
510
-
511
- found_inherited:
512
-
513
- // Specialize the inherited conformance, if necessary.
514
- if (!subs.empty ()) {
515
- TypeSubstitutionMap subMap;
516
- ArchetypeConformanceMap conformanceMap;
517
-
518
- // Fill in the substitution and conformance maps.
519
- for (auto archAndSub : subs) {
520
- auto arch = archAndSub.first ;
521
- auto sub = archAndSub.second ;
522
- conformanceMap[arch] = sub.getConformances ();
523
- if (arch->isPrimary ())
524
- subMap[arch] = sub.getReplacement ();
525
- }
526
- return foundInherited->subst (getDeclContext ()->getParentModule (),
527
- getType (), subs.getSubstitutions (),
528
- subMap, conformanceMap);
529
- }
530
- assert ((getType ()->isEqual (foundInherited->getType ()) ||
531
- foundInherited->getType ()->isExactSuperclassOf (getType (), nullptr ))
532
- && " inherited conformance does not match type" );
533
- return foundInherited;
534
530
}
535
531
536
532
#pragma mark Protocol conformance lookup
0 commit comments