Skip to content

Commit 63f5a8d

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 706f84a commit 63f5a8d

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
@@ -3290,57 +3290,36 @@ void ConformanceChecker::ensureRequirementsAreSatisfied(
32903290
= Conformance->populateSignatureConformances();
32913291

32923292
class GatherConformancesListener : public GenericRequirementsCheckListener {
3293-
TypeChecker &tc;
32943293
NormalProtocolConformance *conformance;
32953294
std::function<void(ProtocolConformanceRef)> &writer;
32963295
public:
32973296
GatherConformancesListener(
3298-
TypeChecker &tc,
3299-
NormalProtocolConformance *conformance,
3300-
std::function<void(ProtocolConformanceRef)> &writer)
3301-
: tc(tc), conformance(conformance), writer(writer) { }
3297+
NormalProtocolConformance *conformance,
3298+
std::function<void(ProtocolConformanceRef)> &writer)
3299+
: conformance(conformance), writer(writer) { }
33023300

33033301
void satisfiedConformance(Type depTy, Type replacementTy,
33043302
ProtocolConformanceRef conformance) override {
33053303
// The conformance will use contextual types, but we want the
33063304
// interface type equivalent.
3307-
3308-
// If we have an inherited conformance for an archetype, dig out the
3309-
// superclass conformance to translate.
3310-
Type inheritedInterfaceType;
33113305
if (conformance.isConcrete() &&
33123306
conformance.getConcrete()->getType()->hasArchetype()) {
33133307
auto concreteConformance = conformance.getConcrete();
3314-
if (concreteConformance->getKind()
3315-
== ProtocolConformanceKind::Inherited &&
3316-
conformance.getConcrete()->getType()->is<ArchetypeType>()) {
3317-
inheritedInterfaceType =
3318-
concreteConformance->getType()->mapTypeOutOfContext();
3319-
concreteConformance =
3320-
cast<InheritedProtocolConformance>(concreteConformance)
3321-
->getInheritedConformance();
3322-
}
33233308

33243309
// Map the conformance.
3325-
// FIXME: It would be so much easier and efficient if we had
3326-
// ProtocolConformance::mapTypesOutOfContext().
33273310
auto interfaceType =
33283311
concreteConformance->getType()->mapTypeOutOfContext();
33293312

3330-
conformance = *tc.conformsToProtocol(
3331-
interfaceType,
3332-
conformance.getRequirement(),
3333-
this->conformance->getDeclContext(),
3334-
(ConformanceCheckFlags::SuppressDependencyTracking|
3335-
ConformanceCheckFlags::SkipConditionalRequirements));
3313+
concreteConformance = concreteConformance->subst(
3314+
interfaceType,
3315+
[](SubstitutableType *type) -> Type {
3316+
if (auto *archetypeType = type->getAs<ArchetypeType>())
3317+
return archetypeType->getInterfaceType();
3318+
return type;
3319+
},
3320+
MakeAbstractConformanceForGenericType());
33363321

3337-
// Reinstate inherited conformance.
3338-
if (inheritedInterfaceType) {
3339-
conformance =
3340-
ProtocolConformanceRef(
3341-
tc.Context.getInheritedConformance(inheritedInterfaceType,
3342-
conformance.getConcrete()));
3343-
}
3322+
conformance = ProtocolConformanceRef(concreteConformance);
33443323
}
33453324

33463325
writer(conformance);
@@ -3356,7 +3335,7 @@ void ConformanceChecker::ensureRequirementsAreSatisfied(
33563335

33573336
return false;
33583337
}
3359-
} listener(TC, Conformance, writer);
3338+
} listener(Conformance, writer);
33603339

33613340
auto result = TC.checkGenericArguments(
33623341
DC, Loc, Loc,

0 commit comments

Comments
 (0)