@@ -98,22 +98,14 @@ ProtocolConformanceRef::subst(Type origType,
98
98
if (isInvalid ())
99
99
return *this ;
100
100
101
- auto substType = origType.subst (subs, conformances,
102
- SubstFlags::UseErrorType);
103
-
104
101
// If we have a concrete conformance, we need to substitute the
105
102
// 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);
117
109
118
110
// Opened existentials trivially conform and do not need to go through
119
111
// substitution map lookup.
@@ -1047,74 +1039,64 @@ bool ProtocolConformance::isVisibleFrom(const DeclContext *dc) const {
1047
1039
}
1048
1040
1049
1041
ProtocolConformance *
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},
1054
1044
LookUpConformanceInSubstitutionMap (subMap));
1055
1045
}
1056
1046
1057
1047
ProtocolConformance *
1058
- ProtocolConformance::subst (Type substType,
1059
- TypeSubstitutionFn subs,
1048
+ ProtocolConformance::subst (TypeSubstitutionFn subs,
1060
1049
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
-
1069
1050
switch (getKind ()) {
1070
1051
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 );
1077
1056
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 );
1080
1062
1081
- return substType->getASTContext ()
1063
+ return substType->getASTContext ()
1082
1064
.getSpecializedConformance (substType,
1083
1065
const_cast <ProtocolConformance *>(this ),
1084
1066
subMap);
1085
- }
1086
-
1087
- assert (substType->isEqual (getType ())
1088
- && " substitution changed non-specialized type?!" );
1089
- return const_cast <ProtocolConformance *>(this );
1090
1067
}
1091
1068
case ProtocolConformanceKind::Inherited: {
1092
1069
// Substitute the base.
1093
1070
auto inheritedConformance
1094
1071
= 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);
1102
1072
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 ()) {
1103
1082
// Substitute into the superclass.
1104
- newBase = inheritedConformance->subst (superclassType, subs, conformances);
1105
- } else {
1106
- newBase = inheritedConformance;
1083
+ inheritedConformance = inheritedConformance->subst (subs, conformances);
1107
1084
}
1108
1085
1086
+ auto substType = origType.subst (subs, conformances,
1087
+ SubstFlags::UseErrorType);
1109
1088
return substType->getASTContext ()
1110
- .getInheritedConformance (substType, newBase );
1089
+ .getInheritedConformance (substType, inheritedConformance );
1111
1090
}
1112
1091
case ProtocolConformanceKind::Specialized: {
1113
1092
// Substitute the substitutions in the specialized conformance.
1114
1093
auto spec = cast<SpecializedProtocolConformance>(this );
1115
1094
auto genericConformance = spec->getGenericConformance ();
1116
1095
auto subMap = spec->getSubstitutionMap ();
1117
1096
1097
+ auto origType = getType ();
1098
+ auto substType = origType.subst (subs, conformances,
1099
+ SubstFlags::UseErrorType);
1118
1100
return substType->getASTContext ()
1119
1101
.getSpecializedConformance (substType, genericConformance,
1120
1102
subMap.subst (subs, conformances));
0 commit comments