From 2b4781597346ec9cc2ab2cb209317606ed0d9ea5 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Tue, 9 Jun 2020 13:03:35 -0700 Subject: [PATCH 1/3] IRGen: Lookup the conformance of an archetype in the right substitution map when computing necessary bindings of abstract cnditional requirements SR-12853 --- lib/IRGen/GenProto.cpp | 7 +++++-- test/IRGen/partial_apply_forwarder.sil | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index 2cb7ba801893d..7c54d83598f0e 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -2749,9 +2749,12 @@ static void addAbstractConditionalRequirements( auto *proto = req.getSecondType()->castTo()->getDecl(); auto ty = req.getFirstType()->getCanonicalType(); - if (!isa(ty)) + auto archetype = dyn_cast(ty); + if (!archetype) continue; - auto conformance = subMap.lookupConformance(ty, proto); + auto *genericEnv = archetype->getGenericEnvironment(); + auto conformance = + genericEnv->getForwardingSubstitutionMap().lookupConformance(ty, proto); if (!conformance.isAbstract()) continue; requirements.insert({ty, conformance.getAbstract()}); diff --git a/test/IRGen/partial_apply_forwarder.sil b/test/IRGen/partial_apply_forwarder.sil index 50ead1c5882c4..d54dbf3f118c3 100644 --- a/test/IRGen/partial_apply_forwarder.sil +++ b/test/IRGen/partial_apply_forwarder.sil @@ -291,7 +291,7 @@ bb0(%0 : $Outer>): return %15 : $() } -sil @$dont_crash_test_capture_specialized_conditional_conformance_nested : $@convention(thin) (Outer>) -> () { +sil @$dont_crash_test_capture_specialized_conditional_conformance_nested : $@convention(thin) (Outer>) -> () { bb0(%0 : $Outer>): %4 = metatype $@thin Outermost>>.Type %5 = function_ref @$closure2 : $@convention(method) (Outermost, Outermost, @thin Outermost.Type) -> Builtin.Int1 From 478e13b9c96040163556dc9d22f972ad616aa3e5 Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Wed, 10 Jun 2020 06:28:27 -0700 Subject: [PATCH 2/3] Address review feedback --- lib/IRGen/GenProto.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index 7c54d83598f0e..0b28c73308c2a 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -2749,14 +2749,13 @@ static void addAbstractConditionalRequirements( auto *proto = req.getSecondType()->castTo()->getDecl(); auto ty = req.getFirstType()->getCanonicalType(); - auto archetype = dyn_cast(ty); + auto archetype = dyn_cast(ty); if (!archetype) continue; auto *genericEnv = archetype->getGenericEnvironment(); auto conformance = genericEnv->getForwardingSubstitutionMap().lookupConformance(ty, proto); - if (!conformance.isAbstract()) - continue; + assert(conformance.isAbstract()); requirements.insert({ty, conformance.getAbstract()}); } // Recursively add conditional requirements. From 8a2bfb046b358cb429b5e8c1eff602d4578c6f5c Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Thu, 11 Jun 2020 07:15:36 -0700 Subject: [PATCH 3/3] No need to lookup the conformance we can just take the protocol from the requirement --- lib/IRGen/GenProto.cpp | 6 +----- test/IRGen/partial_apply_forwarder.sil | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/lib/IRGen/GenProto.cpp b/lib/IRGen/GenProto.cpp index 0b28c73308c2a..3e7d81c2ca5fd 100644 --- a/lib/IRGen/GenProto.cpp +++ b/lib/IRGen/GenProto.cpp @@ -2752,11 +2752,7 @@ static void addAbstractConditionalRequirements( auto archetype = dyn_cast(ty); if (!archetype) continue; - auto *genericEnv = archetype->getGenericEnvironment(); - auto conformance = - genericEnv->getForwardingSubstitutionMap().lookupConformance(ty, proto); - assert(conformance.isAbstract()); - requirements.insert({ty, conformance.getAbstract()}); + requirements.insert({ty, proto}); } // Recursively add conditional requirements. for (auto &conf : subMap.getConformances()) { diff --git a/test/IRGen/partial_apply_forwarder.sil b/test/IRGen/partial_apply_forwarder.sil index d54dbf3f118c3..9c155222a0812 100644 --- a/test/IRGen/partial_apply_forwarder.sil +++ b/test/IRGen/partial_apply_forwarder.sil @@ -255,6 +255,9 @@ protocol MyEquatable { static func isEqual (lhs: Self, rhs: Self) -> Builtin.Int1 } +protocol MyExtended : MyEquatable { + func extended() +} public struct Inner { public init() public init(_ e: Element) @@ -278,7 +281,7 @@ public struct Outermost { sil @$closure : $@convention(method) (Outer, Outer, @thin Outer.Type) -> Builtin.Int1 sil @$closure2 : $@convention(method) (Outermost, Outermost, @thin Outermost.Type) -> Builtin.Int1 -sil @$dont_crash_test_capture_specialized_conditional_conformance : $@convention(thin) (Outer>) -> () { +sil @$dont_crash_test_capture_specialized_conditional_conformance : $@convention(thin) (Outer>) -> () { bb0(%0 : $Outer>): %2 = alloc_stack $Outer> store %0 to %2 : $*Outer> @@ -291,6 +294,23 @@ bb0(%0 : $Outer>): return %15 : $() } +protocol AssocType { + associatedtype A : MyExtended +} + +sil @$dont_crash_test_capture_specialized_conditional_conformance_associated_type : $@convention(thin) (Outer>) -> () { +bb0(%0 : $Outer>): + %2 = alloc_stack $Outer> + store %0 to %2 : $*Outer> + %4 = metatype $@thin Outer>.Type + %5 = function_ref @$closure : $@convention(method) <τ_0_0 where τ_0_0 : MyEquatable> (Outer<τ_0_0>, Outer<τ_0_0>, @thin Outer<τ_0_0>.Type) -> Builtin.Int1 + %6 = partial_apply [callee_guaranteed] %5>(%4) : $@convention(method) <τ_0_0 where τ_0_0 : MyEquatable> (Outer<τ_0_0>, Outer<τ_0_0>, @thin Outer<τ_0_0>.Type) -> Builtin.Int1 + strong_release %6 : $@callee_guaranteed (Outer>, Outer>) -> Builtin.Int1 + dealloc_stack %2 : $*Outer> + %15 = tuple () + return %15 : $() +} + sil @$dont_crash_test_capture_specialized_conditional_conformance_nested : $@convention(thin) (Outer>) -> () { bb0(%0 : $Outer>): %4 = metatype $@thin Outermost>>.Type