Skip to content

Commit 0a38a47

Browse files
Merge pull request #31349 from aschwaighofer/fix_sr_12571
SILCombine: Fix update of substitution map when substituting opened opaque archetypes
2 parents 07738e5 + b5f5495 commit 0a38a47

File tree

7 files changed

+115
-5
lines changed

7 files changed

+115
-5
lines changed

include/swift/AST/ProtocolConformanceRef.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ class ProtocolConformanceRef {
134134
void dump(llvm::raw_ostream &out, unsigned indent = 0,
135135
bool details = true) const;
136136

137+
void print(llvm::raw_ostream &out) const;
138+
137139
bool operator==(ProtocolConformanceRef other) const {
138140
return Union == other.Union;
139141
}

include/swift/AST/Type.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,9 @@ enum class SubstFlags {
148148
DesugarMemberTypes = 0x02,
149149
/// Substitute types involving opaque type archetypes.
150150
SubstituteOpaqueArchetypes = 0x04,
151+
/// Force substitution of opened archetypes. Normally -- without these flag --
152+
/// opened archetype conformances are not substituted.
153+
ForceSubstituteOpenedExistentials = 0x08,
151154
};
152155

153156
/// Options for performing substitutions into a type.

lib/AST/ASTDumper.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3330,6 +3330,13 @@ void ProtocolConformanceRef::dump(llvm::raw_ostream &out, unsigned indent,
33303330

33313331
dumpProtocolConformanceRefRec(*this, out, indent, visited);
33323332
}
3333+
3334+
void ProtocolConformanceRef::print(llvm::raw_ostream &out) const {
3335+
llvm::SmallPtrSet<const ProtocolConformance *, 8> visited;
3336+
dumpProtocolConformanceRefRec(*this, out, 0, visited);
3337+
3338+
}
3339+
33333340
void ProtocolConformance::dump() const {
33343341
auto &out = llvm::errs();
33353342
dump(out);

lib/AST/ProtocolConformance.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ ProtocolConformanceRef::subst(Type origType,
122122

123123
// Opened existentials trivially conform and do not need to go through
124124
// substitution map lookup.
125-
if (substType->isOpenedExistential())
125+
if (substType->isOpenedExistential() &&
126+
!options.contains(SubstFlags::ForceSubstituteOpenedExistentials))
126127
return *this;
127128

128129
auto *proto = getRequirement();

lib/SIL/IR/SILPrinter.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ static void printGenericSpecializationInfo(
375375
raw_ostream &OS, StringRef Kind, StringRef Name,
376376
const GenericSpecializationInformation *SpecializationInfo,
377377
SubstitutionMap Subs = { }) {
378-
if (!SpecializationInfo)
378+
if (!SpecializationInfo && Subs.empty())
379379
return;
380380

381381
auto PrintSubstitutions = [&](SubstitutionMap Subs) {
@@ -384,6 +384,11 @@ static void printGenericSpecializationInfo(
384384
[&](Type type) { OS << type; },
385385
[&] { OS << ", "; });
386386
OS << '>';
387+
OS << " conformances <";
388+
interleave(Subs.getConformances(),
389+
[&](ProtocolConformanceRef conf) { conf.print(OS); },
390+
[&] { OS << ", ";});
391+
OS << '>';
387392
};
388393

389394
OS << "// Generic specialization information for " << Kind << " " << Name;
@@ -716,7 +721,9 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
716721
Ctx.printInstructionCallBack(&I);
717722
if (SILPrintGenericSpecializationInfo) {
718723
if (auto AI = ApplySite::isa(const_cast<SILInstruction *>(&I)))
719-
if (AI.getSpecializationInfo() && AI.getCalleeFunction())
724+
if ((AI.getSpecializationInfo() ||
725+
!AI.getSubstitutionMap().empty()) &&
726+
AI.getCalleeFunction())
720727
printGenericSpecializationInfo(
721728
PrintState.OS, "call-site", AI.getCalleeFunction()->getName(),
722729
AI.getSpecializationInfo(), AI.getSubstitutionMap());

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,8 @@ SILInstruction *SILCombiner::createApplyWithConcreteType(
859859
return CEI.lookupExistentialConformance(proto);
860860
}
861861
return ProtocolConformanceRef(proto);
862-
});
862+
},
863+
SubstFlags::ForceSubstituteOpenedExistentials);
863864
}
864865

865866
// We need to make sure that we can a) update Apply to use the new args and b)

test/SILOptimizer/sil_combine_concrete_existential.sil

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %target-sil-opt -enable-objc-interop -enable-sil-verify-all %s -sil-combine | %FileCheck %s
1+
// RUN: %target-sil-opt -enable-objc-interop -enable-sil-verify-all %s -sil-combine -sil-print-generic-specialization-info | %FileCheck %s
2+
// RUN: %target-swift-frontend -O %s -emit-ir
23

34
// These tests exercise the same SILCombine optimization as
45
// existential_type_propagation.sil, but cover additional corner
@@ -615,3 +616,91 @@ bb0(%0 : $*τ_0_0, %1 : $*τ_0_2, %2 : $*τ_0_1):
615616
dealloc_stack %5 : $*P1
616617
return %25 : $()
617618
}
619+
620+
621+
public class MyObject {
622+
deinit
623+
init()
624+
}
625+
626+
public protocol SubscriptionViewControllerDelegate { }
627+
628+
public class SubscriptionViewController {
629+
deinit
630+
init()
631+
}
632+
633+
public protocol ResourceKitProtocol : MyObject { }
634+
635+
public protocol ResourceKitDelegate {
636+
func subscriptionViewController(for resourceKit: ResourceKitProtocol)
637+
}
638+
639+
class ViewController : ResourceKitDelegate {
640+
func subscriptionViewController(for resourceKit: ResourceKitProtocol)
641+
deinit
642+
init()
643+
}
644+
645+
class SubscriptionViewControllerBuilder {
646+
@_hasStorage final let delegate: SubscriptionViewControllerDelegate { get }
647+
init(delegate: SubscriptionViewControllerDelegate)
648+
deinit
649+
}
650+
651+
extension MyObject : SubscriptionViewControllerDelegate { }
652+
653+
// Make sure that we correctly update the substitution map of the apply.
654+
// To satisfy ``τ_0_0 : SubscriptionViewControllerDelegate`` the updated
655+
// substitution map of
656+
// apply %10<$@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol>
657+
// needs to contain the concrete conformance
658+
// ``(normal_conformance type=NSObject protocol=SubscriptionViewControllerDelegate)``
659+
// not ``(abstract_conformance protocol=SubscriptionViewControllerDelegate)``
660+
661+
sil @callee2 : $@convention(thin) <τ_0_0 where τ_0_0 : SubscriptionViewControllerDelegate> (@in τ_0_0, @thick SubscriptionViewControllerBuilder.Type) -> @owned SubscriptionViewControllerBuilder
662+
663+
// CHECK: sil @test_opend_archeype_concrete_conformance_substitution : $@convention(method) (@guaranteed ResourceKitProtocol, @guaranteed ViewController) -> () {
664+
// CHECK: bb0([[ARG:%.*]] : $ResourceKitProtocol, [[ARG2:%.*]] : $ViewController):
665+
// CHECK: [[T1:%.*]] = metatype $@thick SubscriptionViewControllerBuilder.Type
666+
// CHECK: [[T2:%.*]] = open_existential_ref [[ARG]] : $ResourceKitProtocol to $@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol
667+
// CHECK: [[T3:%.*]] = alloc_stack $SubscriptionViewControllerDelegate
668+
// CHECK: [[T4:%.*]] = init_existential_addr [[T3]] : $*SubscriptionViewControllerDelegate, $@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol
669+
// CHECK: store [[T2]] to [[T4]] : $*@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol
670+
// CHECK: [[T5:%.*]] = function_ref @callee2 : $@convention(thin) <τ_0_0 where τ_0_0 : SubscriptionViewControllerDelegate> (@in τ_0_0, @thick SubscriptionViewControllerBuilder.Type) -> @owned SubscriptionViewControllerBuilder
671+
// CHECK: [[T6:%.*]] = alloc_stack $@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol
672+
// CHECK: copy_addr [[T4]] to [initialization] [[T6]] : $*@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol
673+
// CHECK: Generic specialization information for call-site callee2 <ResourceKitProtocol> conformances <(inherited_conformance type=ResourceKitProtocol protocol=SubscriptionViewControllerDelegate
674+
// CHECK: (normal_conformance type=MyObject protocol=SubscriptionViewControllerDelegate))>:
675+
// CHECK: apply [[T5]]<@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol>([[T6]], [[T1]])
676+
677+
sil @test_opend_archeype_concrete_conformance_substitution : $@convention(method) (@guaranteed ResourceKitProtocol, @guaranteed ViewController) -> () {
678+
bb0(%0 : $ResourceKitProtocol, %1 : $ViewController):
679+
%4 = metatype $@thick SubscriptionViewControllerBuilder.Type
680+
%5 = open_existential_ref %0 : $ResourceKitProtocol to $@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol
681+
%6 = alloc_stack $SubscriptionViewControllerDelegate
682+
%7 = init_existential_addr %6 : $*SubscriptionViewControllerDelegate, $@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol
683+
strong_retain %5 : $@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol
684+
store %5 to %7 : $*@opened("E4D92D2A-8893-11EA-9C89-ACDE48001122") ResourceKitProtocol
685+
%10 = function_ref @callee2: $@convention(thin) <τ_0_0 where τ_0_0 : SubscriptionViewControllerDelegate> (@in τ_0_0, @thick SubscriptionViewControllerBuilder.Type) -> @owned SubscriptionViewControllerBuilder
686+
%11 = open_existential_addr mutable_access %6 : $*SubscriptionViewControllerDelegate to $*@opened("FAA82796-8893-11EA-9C89-ACDE48001122") SubscriptionViewControllerDelegate
687+
%12 = alloc_stack $@opened("FAA82796-8893-11EA-9C89-ACDE48001122") SubscriptionViewControllerDelegate
688+
copy_addr %11 to [initialization] %12 : $*@opened("FAA82796-8893-11EA-9C89-ACDE48001122") SubscriptionViewControllerDelegate
689+
%14 = apply %10<@opened("FAA82796-8893-11EA-9C89-ACDE48001122") SubscriptionViewControllerDelegate>(%12, %4) : $@convention(thin) <τ_0_0 where τ_0_0 : SubscriptionViewControllerDelegate> (@in τ_0_0, @thick SubscriptionViewControllerBuilder.Type) -> @owned SubscriptionViewControllerBuilder
690+
destroy_addr %6 : $*SubscriptionViewControllerDelegate
691+
dealloc_stack %12 : $*@opened("FAA82796-8893-11EA-9C89-ACDE48001122") SubscriptionViewControllerDelegate
692+
dealloc_stack %6 : $*SubscriptionViewControllerDelegate
693+
strong_release %14 : $SubscriptionViewControllerBuilder
694+
%19 = tuple ()
695+
return %19 : $()
696+
}
697+
698+
sil_vtable SubscriptionViewControllerBuilder {}
699+
sil_vtable SubscriptionViewController {}
700+
sil_vtable ViewController {}
701+
sil_vtable CCCC {}
702+
sil_vtable CC {}
703+
sil_vtable C {}
704+
sil_vtable C_PQ {}
705+
sil_vtable CDefaultStatic {}
706+
sil_vtable MyObject {}

0 commit comments

Comments
 (0)