Skip to content

Commit f242a23

Browse files
committed
Sema: Simplify GatherConformancesListener
The inherited conformance check was dead because the type of a conformance can never be an archetype. Also, take care to substitute the conformance we are given, instead of throwing it out and looking up a new one, because we want to be careful to preserve any existing substitutions. Part of the fix for <rdar://problem/40164371>.
1 parent 1ff91fe commit f242a23

File tree

1 file changed

+13
-34
lines changed

1 file changed

+13
-34
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3318,57 +3318,36 @@ void ConformanceChecker::ensureRequirementsAreSatisfied(
33183318
= Conformance->populateSignatureConformances();
33193319

33203320
class GatherConformancesListener : public GenericRequirementsCheckListener {
3321-
TypeChecker &tc;
33223321
NormalProtocolConformance *conformance;
33233322
std::function<void(ProtocolConformanceRef)> &writer;
33243323
public:
33253324
GatherConformancesListener(
3326-
TypeChecker &tc,
3327-
NormalProtocolConformance *conformance,
3328-
std::function<void(ProtocolConformanceRef)> &writer)
3329-
: tc(tc), conformance(conformance), writer(writer) { }
3325+
NormalProtocolConformance *conformance,
3326+
std::function<void(ProtocolConformanceRef)> &writer)
3327+
: conformance(conformance), writer(writer) { }
33303328

33313329
void satisfiedConformance(Type depTy, Type replacementTy,
33323330
ProtocolConformanceRef conformance) override {
33333331
// The conformance will use contextual types, but we want the
33343332
// interface type equivalent.
3335-
3336-
// If we have an inherited conformance for an archetype, dig out the
3337-
// superclass conformance to translate.
3338-
Type inheritedInterfaceType;
33393333
if (conformance.isConcrete() &&
33403334
conformance.getConcrete()->getType()->hasArchetype()) {
33413335
auto concreteConformance = conformance.getConcrete();
3342-
if (concreteConformance->getKind()
3343-
== ProtocolConformanceKind::Inherited &&
3344-
conformance.getConcrete()->getType()->is<ArchetypeType>()) {
3345-
inheritedInterfaceType =
3346-
concreteConformance->getType()->mapTypeOutOfContext();
3347-
concreteConformance =
3348-
cast<InheritedProtocolConformance>(concreteConformance)
3349-
->getInheritedConformance();
3350-
}
33513336

33523337
// Map the conformance.
3353-
// FIXME: It would be so much easier and efficient if we had
3354-
// ProtocolConformance::mapTypesOutOfContext().
33553338
auto interfaceType =
33563339
concreteConformance->getType()->mapTypeOutOfContext();
33573340

3358-
conformance = *tc.conformsToProtocol(
3359-
interfaceType,
3360-
conformance.getRequirement(),
3361-
this->conformance->getDeclContext(),
3362-
(ConformanceCheckFlags::SuppressDependencyTracking|
3363-
ConformanceCheckFlags::SkipConditionalRequirements));
3341+
concreteConformance = concreteConformance->subst(
3342+
interfaceType,
3343+
[](SubstitutableType *type) -> Type {
3344+
if (auto *archetypeType = type->getAs<ArchetypeType>())
3345+
return archetypeType->getInterfaceType();
3346+
return type;
3347+
},
3348+
MakeAbstractConformanceForGenericType());
33643349

3365-
// Reinstate inherited conformance.
3366-
if (inheritedInterfaceType) {
3367-
conformance =
3368-
ProtocolConformanceRef(
3369-
tc.Context.getInheritedConformance(inheritedInterfaceType,
3370-
conformance.getConcrete()));
3371-
}
3350+
conformance = ProtocolConformanceRef(concreteConformance);
33723351
}
33733352

33743353
writer(conformance);
@@ -3384,7 +3363,7 @@ void ConformanceChecker::ensureRequirementsAreSatisfied(
33843363

33853364
return false;
33863365
}
3387-
} listener(TC, Conformance, writer);
3366+
} listener(Conformance, writer);
33883367

33893368
auto result = TC.checkGenericArguments(
33903369
DC, Loc, Loc,

0 commit comments

Comments
 (0)