Skip to content

Commit 9d09f93

Browse files
committed
AST: Correctly use inherited conformances in RequirementEnvironment
When the conforming type is a class-constrained type parameter or archetype, we must wrap the concrete superclass conformance in an inherited conformance. This is now flagged by SubstitutionMap::verify().
1 parent 2f28b9b commit 9d09f93

File tree

1 file changed

+24
-11
lines changed

1 file changed

+24
-11
lines changed

lib/AST/RequirementEnvironment.cpp

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -118,23 +118,36 @@ RequirementEnvironment::RequirementEnvironment(
118118
}
119119
return substGenericParam;
120120
},
121-
[selfType, substConcreteType, conformance, conformanceDC, &ctx](
121+
[selfType, substConcreteType, conformance, conformanceDC, covariantSelf, &ctx](
122122
CanType type, Type replacement, ProtocolDecl *proto)
123123
-> ProtocolConformanceRef {
124124
// The protocol 'Self' conforms concretely to the conforming type.
125125
if (type->isEqual(selfType)) {
126-
ProtocolConformance *specialized = conformance;
127-
if (conformance && conformance->getGenericSignature()) {
128-
auto concreteSubs =
129-
substConcreteType->getContextSubstitutionMap(conformanceDC);
130-
specialized =
131-
ctx.getSpecializedConformance(substConcreteType,
132-
cast<NormalProtocolConformance>(conformance),
133-
concreteSubs);
134-
}
126+
ASSERT(covariantSelf || replacement->isEqual(substConcreteType));
127+
128+
if (conformance) {
129+
ProtocolConformance *specialized = conformance;
130+
131+
if (conformance->getGenericSignature()) {
132+
auto concreteSubs =
133+
substConcreteType->getContextSubstitutionMap(conformanceDC);
134+
specialized =
135+
ctx.getSpecializedConformance(substConcreteType,
136+
cast<NormalProtocolConformance>(conformance),
137+
concreteSubs);
138+
}
139+
140+
// findWitnessedObjCRequirements() does a weird thing by passing in a
141+
// DC that is not the conformance DC. Work around it here.
142+
if (!specialized->getType()->isEqual(replacement)) {
143+
ASSERT(specialized->getType()->isExactSuperclassOf(substConcreteType));
144+
ASSERT(covariantSelf ? replacement->is<GenericTypeParamType>()
145+
: replacement->isEqual(substConcreteType));
146+
specialized = ctx.getInheritedConformance(replacement, specialized);
147+
}
135148

136-
if (specialized)
137149
return ProtocolConformanceRef(specialized);
150+
}
138151
}
139152

140153
// All other generic parameters come from the requirement itself

0 commit comments

Comments
 (0)