@@ -98,22 +98,14 @@ ProtocolConformanceRef::subst(Type origType,
9898 if (isInvalid ())
9999 return *this ;
100100
101- auto substType = origType.subst (subs, conformances,
102- SubstFlags::UseErrorType);
103-
104101 // If we have a concrete conformance, we need to substitute the
105102 // conformance to apply to the new type.
106- if (isConcrete ()) {
107- auto concrete = getConcrete ();
108- if (auto classDecl = concrete->getType ()->getClassOrBoundGenericClass ()) {
109- // If this is a class, we need to traffic in the actual type that
110- // implements the protocol, not 'Self' and not any subclasses (with their
111- // inherited conformances).
112- substType = substType->getSuperclassForDecl (classDecl);
113- }
114- return ProtocolConformanceRef (
115- getConcrete ()->subst (substType, subs, conformances));
116- }
103+ if (isConcrete ())
104+ return ProtocolConformanceRef (getConcrete ()->subst (subs, conformances));
105+
106+ // Otherwise, compute the substituted type.
107+ auto substType = origType.subst (subs, conformances,
108+ SubstFlags::UseErrorType);
117109
118110 // Opened existentials trivially conform and do not need to go through
119111 // substitution map lookup.
@@ -1047,74 +1039,64 @@ bool ProtocolConformance::isVisibleFrom(const DeclContext *dc) const {
10471039}
10481040
10491041ProtocolConformance *
1050- ProtocolConformance::subst (Type substType,
1051- SubstitutionMap subMap) const {
1052- return subst (substType,
1053- QuerySubstitutionMap{subMap},
1042+ ProtocolConformance::subst (SubstitutionMap subMap) const {
1043+ return subst (QuerySubstitutionMap{subMap},
10541044 LookUpConformanceInSubstitutionMap (subMap));
10551045}
10561046
10571047ProtocolConformance *
1058- ProtocolConformance::subst (Type substType,
1059- TypeSubstitutionFn subs,
1048+ ProtocolConformance::subst (TypeSubstitutionFn subs,
10601049 LookupConformanceFn conformances) const {
1061- // ModuleDecl::lookupConformance() strips off dynamic Self, so
1062- // we should do the same here.
1063- if (auto selfType = substType->getAs <DynamicSelfType>())
1064- substType = selfType->getSelfType ();
1065-
1066- if (getType ()->isEqual (substType))
1067- return const_cast <ProtocolConformance *>(this );
1068-
10691050 switch (getKind ()) {
10701051 case ProtocolConformanceKind::Normal: {
1071- if (substType->isSpecialized ()) {
1072- assert (getType ()->isSpecialized ()
1073- && " substitution mapped non-specialized to specialized?!" );
1074- assert (getType ()->getNominalOrBoundGenericNominal ()
1075- == substType->getNominalOrBoundGenericNominal ()
1076- && " substitution mapped to different nominal?!" );
1052+ auto origType = getType ();
1053+ if (!origType->hasTypeParameter () &&
1054+ !origType->hasArchetype ())
1055+ return const_cast <ProtocolConformance *>(this );
10771056
1078- auto subMap = SubstitutionMap::get (getGenericSignature (),
1079- subs, conformances);
1057+ auto subMap = SubstitutionMap::get (getGenericSignature (),
1058+ subs, conformances);
1059+ auto substType = origType.subst (subMap, SubstFlags::UseErrorType);
1060+ if (substType->isEqual (origType))
1061+ return const_cast <ProtocolConformance *>(this );
10801062
1081- return substType->getASTContext ()
1063+ return substType->getASTContext ()
10821064 .getSpecializedConformance (substType,
10831065 const_cast <ProtocolConformance *>(this ),
10841066 subMap);
1085- }
1086-
1087- assert (substType->isEqual (getType ())
1088- && " substitution changed non-specialized type?!" );
1089- return const_cast <ProtocolConformance *>(this );
10901067 }
10911068 case ProtocolConformanceKind::Inherited: {
10921069 // Substitute the base.
10931070 auto inheritedConformance
10941071 = cast<InheritedProtocolConformance>(this )->getInheritedConformance ();
1095- ProtocolConformance *newBase;
1096- if (inheritedConformance->getType ()->isSpecialized ()) {
1097- // Follow the substituted type up the superclass chain until we reach
1098- // the underlying class type.
1099- auto targetClass =
1100- inheritedConformance->getType ()->getClassOrBoundGenericClass ();
1101- auto superclassType = substType->getSuperclassForDecl (targetClass);
11021072
1073+ auto origType = getType ();
1074+ if (!origType->hasTypeParameter () &&
1075+ !origType->hasArchetype ()) {
1076+ return const_cast <ProtocolConformance *>(this );
1077+ }
1078+
1079+ auto origBaseType = inheritedConformance->getType ();
1080+ if (origBaseType->hasTypeParameter () ||
1081+ origBaseType->hasArchetype ()) {
11031082 // Substitute into the superclass.
1104- newBase = inheritedConformance->subst (superclassType, subs, conformances);
1105- } else {
1106- newBase = inheritedConformance;
1083+ inheritedConformance = inheritedConformance->subst (subs, conformances);
11071084 }
11081085
1086+ auto substType = origType.subst (subs, conformances,
1087+ SubstFlags::UseErrorType);
11091088 return substType->getASTContext ()
1110- .getInheritedConformance (substType, newBase );
1089+ .getInheritedConformance (substType, inheritedConformance );
11111090 }
11121091 case ProtocolConformanceKind::Specialized: {
11131092 // Substitute the substitutions in the specialized conformance.
11141093 auto spec = cast<SpecializedProtocolConformance>(this );
11151094 auto genericConformance = spec->getGenericConformance ();
11161095 auto subMap = spec->getSubstitutionMap ();
11171096
1097+ auto origType = getType ();
1098+ auto substType = origType.subst (subs, conformances,
1099+ SubstFlags::UseErrorType);
11181100 return substType->getASTContext ()
11191101 .getSpecializedConformance (substType, genericConformance,
11201102 subMap.subst (subs, conformances));
0 commit comments