Skip to content

Commit 449766f

Browse files
committed
IRGen: Fix specialized conformances with abstract conditional requirements in the partial apply forwarder
2nd attempt. rdar://59723512
1 parent b926250 commit 449766f

File tree

2 files changed

+28
-2
lines changed

2 files changed

+28
-2
lines changed

lib/IRGen/GenProto.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2743,8 +2743,7 @@ void NecessaryBindings::addTypeMetadata(CanType type) {
27432743
static void addAbstractConditionalRequirements(
27442744
SpecializedProtocolConformance *specializedConformance,
27452745
llvm::SetVector<GenericRequirement> &requirements) {
2746-
auto module = specializedConformance->getDeclContext()->getParentModule();
2747-
auto subMap = specializedConformance->getSubstitutions(module);
2746+
auto subMap = specializedConformance->getSubstitutionMap();
27482747
auto condRequirements =
27492748
specializedConformance->getConditionalRequirementsIfAvailable();
27502749
if (!condRequirements)
@@ -2756,11 +2755,23 @@ static void addAbstractConditionalRequirements(
27562755
auto *proto =
27572756
req.getSecondType()->castTo<ProtocolType>()->getDecl();
27582757
auto ty = req.getFirstType()->getCanonicalType();
2758+
if (!isa<ArchetypeType>(ty))
2759+
continue;
27592760
auto conformance = subMap.lookupConformance(ty, proto);
27602761
if (!conformance.isAbstract())
27612762
continue;
27622763
requirements.insert({ty, conformance.getAbstract()});
27632764
}
2765+
// Recursively add conditional requirements.
2766+
for (auto &conf : subMap.getConformances()) {
2767+
if (conf.isAbstract())
2768+
continue;
2769+
auto specializedConf =
2770+
dyn_cast<SpecializedProtocolConformance>(conf.getConcrete());
2771+
if (!specializedConf)
2772+
continue;
2773+
addAbstractConditionalRequirements(specializedConf, requirements);
2774+
}
27642775
}
27652776

27662777
void NecessaryBindings::addProtocolConformance(CanType type,

test/IRGen/partial_apply_forwarder.sil

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,11 @@ extension Outer : MyEquatable where Value : MyEquatable {
269269
public static func isEqual (lhs: Outer<Value>, rhs: Outer<Value>) -> Builtin.Int1
270270
}
271271

272+
public struct Outermost<Value> {
273+
}
274+
272275
sil @$closure : $@convention(method) <Value where Value : MyEquatable> (Outer<Value>, Outer<Value>, @thin Outer<Value>.Type) -> Builtin.Int1
276+
sil @$closure2 : $@convention(method) <Value where Value : MyEquatable> (Outermost<Value>, Outermost<Value>, @thin Outermost<Value>.Type) -> Builtin.Int1
273277

274278
sil @$dont_crash_test_caputre_specialized_conditional_conformance : $@convention(thin) <Element where Element : MyEquatable> (Outer<Inner<Element>>) -> () {
275279
bb0(%0 : $Outer<Inner<Element>>):
@@ -284,6 +288,17 @@ bb0(%0 : $Outer<Inner<Element>>):
284288
return %15 : $()
285289
}
286290

291+
sil @$dont_crash_test_caputre_specialized_conditional_conformance_nested : $@convention(thin) <Element where Element : MyEquatable> (Outer<Inner<Element>>) -> () {
292+
bb0(%0 : $Outer<Inner<Element>>):
293+
%4 = metatype $@thin Outermost<Outer<Inner<Element>>>.Type
294+
%5 = function_ref @$closure2 : $@convention(method) <Value where Value : MyEquatable> (Outermost<Value>, Outermost<Value>, @thin Outermost<Value>.Type) -> Builtin.Int1
295+
%6 = partial_apply [callee_guaranteed] %5<Outer<Inner<Element>>>(%4) : $@convention(method) <Value where Value : MyEquatable> (Outermost<Value>, Outermost<Value>, @thin Outermost<Value>.Type) -> Builtin.Int1
296+
strong_release %6 : $@callee_guaranteed (Outermost<Outer<Inner<Element>>>, Outermost<Outer<Inner<Element>>>) -> Builtin.Int1
297+
%15 = tuple ()
298+
return %15 : $()
299+
}
300+
301+
287302
sil_vtable WeakBox {}
288303
sil_vtable C {}
289304
sil_vtable D {}

0 commit comments

Comments
 (0)