@@ -347,46 +347,19 @@ GenericSignature ProtocolConformance::getGenericSignature() const {
347347}
348348
349349SubstitutionMap ProtocolConformance::getSubstitutions (ModuleDecl *M) const {
350- // Walk down to the base NormalProtocolConformance.
351- SubstitutionMap subMap;
352- const ProtocolConformance *parent = this ;
353- while (!isa<RootProtocolConformance>(parent)) {
354- switch (parent->getKind ()) {
355- case ProtocolConformanceKind::Normal:
356- case ProtocolConformanceKind::Self:
357- case ProtocolConformanceKind::Builtin:
358- llvm_unreachable (" should have exited the loop?!" );
359- case ProtocolConformanceKind::Inherited:
360- parent =
361- cast<InheritedProtocolConformance>(parent)->getInheritedConformance ();
362- break ;
363- case ProtocolConformanceKind::Specialized: {
364- auto SC = cast<SpecializedProtocolConformance>(parent);
365- parent = SC->getGenericConformance ();
366- assert (subMap.empty () && " multiple conformance specializations?!" );
367- subMap = SC->getSubstitutionMap ();
368- break ;
369- }
370- }
371- }
350+ const ProtocolConformance *conformance = this ;
372351
373- // Found something; we're done!
374- if (!subMap.empty ())
375- return subMap;
352+ if (auto *inheritedC = dyn_cast<InheritedProtocolConformance>(conformance))
353+ conformance = inheritedC->getInheritedConformance ();
376354
377- // If the normal conformance is for a generic type, and we didn't hit a
378- // specialized conformance, collect the substitutions from the generic type.
379- // FIXME: The AST should do this for us.
380- const NormalProtocolConformance *normalC =
381- dyn_cast<NormalProtocolConformance>(parent);
382- if (!normalC)
383- return SubstitutionMap ();
355+ if (auto *specializedC = dyn_cast<SpecializedProtocolConformance>(conformance))
356+ return specializedC->getSubstitutionMap ();
384357
385- if (!normalC->getType ()->isSpecialized ())
386- return SubstitutionMap ();
358+ auto *rootC = cast<RootProtocolConformance>(conformance);
359+ if (auto genericSig = rootC->getGenericSignature ())
360+ return genericSig->getIdentitySubstitutionMap ();
387361
388- auto *DC = normalC->getDeclContext ();
389- return normalC->getType ()->getContextSubstitutionMap (M, DC);
362+ return SubstitutionMap ();
390363}
391364
392365bool RootProtocolConformance::isInvalid () const {
@@ -957,14 +930,11 @@ void NormalProtocolConformance::overrideWitness(ValueDecl *requirement,
957930
958931SpecializedProtocolConformance::SpecializedProtocolConformance (
959932 Type conformingType,
960- ProtocolConformance *genericConformance,
933+ RootProtocolConformance *genericConformance,
961934 SubstitutionMap substitutions)
962935 : ProtocolConformance(ProtocolConformanceKind::Specialized, conformingType),
963936 GenericConformance(genericConformance),
964- GenericSubstitutions(substitutions)
965- {
966- assert (genericConformance->getKind () != ProtocolConformanceKind::Specialized);
967- }
937+ GenericSubstitutions(substitutions) {}
968938
969939void SpecializedProtocolConformance::computeConditionalRequirements () const {
970940 // already computed?
@@ -1133,22 +1103,12 @@ ProtocolConformance::getRootNormalConformance() const {
11331103const RootProtocolConformance *
11341104ProtocolConformance::getRootConformance () const {
11351105 const ProtocolConformance *C = this ;
1136- while (true ) {
1137- switch (C->getKind ()) {
1138- case ProtocolConformanceKind::Normal:
1139- case ProtocolConformanceKind::Self:
1140- case ProtocolConformanceKind::Builtin:
1141- return cast<RootProtocolConformance>(C);
1142- case ProtocolConformanceKind::Inherited:
1143- C = cast<InheritedProtocolConformance>(C)
1144- ->getInheritedConformance ();
1145- break ;
1146- case ProtocolConformanceKind::Specialized:
1147- C = cast<SpecializedProtocolConformance>(C)
1148- ->getGenericConformance ();
1149- break ;
1150- }
1151- }
1106+ if (auto *inheritedC = dyn_cast<InheritedProtocolConformance>(C))
1107+ C = inheritedC->getInheritedConformance ();
1108+ if (auto *specializedC = dyn_cast<SpecializedProtocolConformance>(C))
1109+ return specializedC->getGenericConformance ();
1110+
1111+ return cast<RootProtocolConformance>(C);
11521112}
11531113
11541114bool ProtocolConformance::isVisibleFrom (const DeclContext *dc) const {
@@ -1181,9 +1141,11 @@ ProtocolConformance::subst(TypeSubstitutionFn subs,
11811141
11821142 auto subMap = SubstitutionMap::get (getGenericSignature (),
11831143 subs, conformances);
1144+
1145+ auto *mutableThis = const_cast <ProtocolConformance *>(this );
11841146 return substType->getASTContext ()
11851147 .getSpecializedConformance (substType,
1186- const_cast <ProtocolConformance *>( this ),
1148+ cast<NormalProtocolConformance>(mutableThis ),
11871149 subMap);
11881150 }
11891151 case ProtocolConformanceKind::Builtin: {
@@ -1660,7 +1622,8 @@ ProtocolConformance *ProtocolConformance::getCanonicalConformance() {
16601622 auto genericConformance = spec->getGenericConformance ();
16611623 return Ctx.getSpecializedConformance (
16621624 getType ()->getCanonicalType (),
1663- genericConformance->getCanonicalConformance (),
1625+ cast<RootProtocolConformance>(
1626+ genericConformance->getCanonicalConformance ()),
16641627 spec->getSubstitutionMap ().getCanonical ());
16651628 }
16661629 }
0 commit comments