Skip to content

Commit e78f16f

Browse files
committed
AST: ProtocolConformance::subst() doesn't need to take substType
1 parent f3f07ec commit e78f16f

File tree

4 files changed

+38
-63
lines changed

4 files changed

+38
-63
lines changed

include/swift/AST/ProtocolConformance.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,13 +315,11 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance {
315315

316316
/// Substitute the conforming type and produce a ProtocolConformance that
317317
/// applies to the substituted type.
318-
ProtocolConformance *subst(Type substType,
319-
SubstitutionMap subMap) const;
318+
ProtocolConformance *subst(SubstitutionMap subMap) const;
320319

321320
/// Substitute the conforming type and produce a ProtocolConformance that
322321
/// applies to the substituted type.
323-
ProtocolConformance *subst(Type substType,
324-
TypeSubstitutionFn subs,
322+
ProtocolConformance *subst(TypeSubstitutionFn subs,
325323
LookupConformanceFn conformances) const;
326324

327325
void dump() const;

lib/AST/ProtocolConformance.cpp

Lines changed: 35 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -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

10491041
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},
10541044
LookUpConformanceInSubstitutionMap(subMap));
10551045
}
10561046

10571047
ProtocolConformance *
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));

lib/IRGen/GenProto.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,8 +1112,7 @@ getWitnessTableLazyAccessFunction(IRGenModule &IGM,
11121112
static ProtocolConformance &mapConformanceIntoContext(IRGenModule &IGM,
11131113
const ProtocolConformance &conf,
11141114
DeclContext *dc) {
1115-
return *conf.subst(dc->mapTypeIntoContext(conf.getType()),
1116-
[&](SubstitutableType *t) -> Type {
1115+
return *conf.subst([&](SubstitutableType *t) -> Type {
11171116
return dc->mapTypeIntoContext(t);
11181117
},
11191118
LookUpConformanceInModule(IGM.getSwiftModule()));

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3366,11 +3366,7 @@ void ConformanceChecker::ensureRequirementsAreSatisfied(
33663366
auto concreteConformance = conformance.getConcrete();
33673367

33683368
// Map the conformance.
3369-
auto interfaceType =
3370-
concreteConformance->getType()->mapTypeOutOfContext();
3371-
33723369
concreteConformance = concreteConformance->subst(
3373-
interfaceType,
33743370
[](SubstitutableType *type) -> Type {
33753371
if (auto *archetypeType = type->getAs<ArchetypeType>())
33763372
return archetypeType->getInterfaceType();

0 commit comments

Comments
 (0)