Skip to content

Commit 71de3d9

Browse files
committed
Optimizer: replace existential archetypes with concrete types in apply instructions
If an apply uses an existential archetype (`@opened("...")`) and the concrete type is known, replace the existential archetype with the concrete type 1. in the apply's substitution map 2. in the arguments, e.g. by inserting address casts For example: ``` %5 = apply %1<@opend("...")>(%2) : <τ_0_0> (τ_0_0) -> () ``` -> ``` %4 = unchecked_addr_cast %2 to $*ConcreteType %5 = apply %1<ConcreteType>(%4) : <τ_0_0> (τ_0_0) -> () ```
1 parent 77dab77 commit 71de3d9

File tree

11 files changed

+326
-19
lines changed

11 files changed

+326
-19
lines changed

SwiftCompilerSources/Sources/Optimizer/InstructionSimplification/SimplifyApply.swift

Lines changed: 143 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
import SIL
14+
import AST
1415

15-
extension ApplyInst : OnoneSimplifiable {
16+
extension ApplyInst : OnoneSimplifiable, SILCombineSimplifiable {
1617
func simplify(_ context: SimplifyContext) {
1718
if tryTransformThickToThinCallee(of: self, context) {
1819
return
@@ -21,13 +22,23 @@ extension ApplyInst : OnoneSimplifiable {
2122
context.erase(instruction: self)
2223
return
2324
}
24-
_ = context.tryDevirtualize(apply: self, isMandatory: false)
25+
if context.tryDevirtualize(apply: self, isMandatory: false) != nil {
26+
return
27+
}
28+
if !context.preserveDebugInfo {
29+
_ = tryReplaceExistentialArchetype(of: self, context)
30+
}
2531
}
2632
}
2733

28-
extension TryApplyInst : OnoneSimplifiable {
34+
extension TryApplyInst : OnoneSimplifiable, SILCombineSimplifiable {
2935
func simplify(_ context: SimplifyContext) {
30-
_ = context.tryDevirtualize(apply: self, isMandatory: false)
36+
if context.tryDevirtualize(apply: self, isMandatory: false) != nil {
37+
return
38+
}
39+
if !context.preserveDebugInfo {
40+
_ = tryReplaceExistentialArchetype(of: self, context)
41+
}
3142
}
3243
}
3344

@@ -61,3 +72,131 @@ private func tryTransformThickToThinCallee(of apply: ApplyInst, _ context: Simpl
6172
}
6273
return false
6374
}
75+
76+
/// If the apply uses an existential archetype (`@opened("...")`) and the concrete type is known,
77+
/// replace the existential archetype with the concrete type
78+
/// 1. in the apply's substitution map
79+
/// 2. in the arguments, e.g. by inserting address casts
80+
/// For example:
81+
/// ```
82+
/// %5 = apply %1<@opend("...")>(%2) : <τ_0_0> (τ_0_0) -> ()
83+
/// ```
84+
/// ->
85+
/// ```
86+
/// %4 = unchecked_addr_cast %2 to $*ConcreteType
87+
/// %5 = apply %1<ConcreteType>(%4) : <τ_0_0> (τ_0_0) -> ()
88+
/// ```
89+
private func tryReplaceExistentialArchetype(of apply: ApplyInst, _ context: SimplifyContext) -> Bool {
90+
if let concreteType = apply.concreteTypeOfDependentExistentialArchetype,
91+
apply.canReplaceExistentialArchetype()
92+
{
93+
let builder = Builder(after: apply, context)
94+
95+
let newApply = builder.createApply(
96+
function: apply.callee,
97+
apply.replaceOpenedArchetypeInSubstituations(withConcreteType: concreteType, context),
98+
arguments: apply.replaceExistentialArchetypeInArguments(withConcreteType: concreteType, context),
99+
isNonThrowing: apply.isNonThrowing, isNonAsync: apply.isNonAsync,
100+
specializationInfo: apply.specializationInfo)
101+
apply.replace(with: newApply, context)
102+
103+
return true
104+
}
105+
return false
106+
}
107+
108+
// The same as the previous function, just for try_apply instructions.
109+
private func tryReplaceExistentialArchetype(of tryApply: TryApplyInst, _ context: SimplifyContext) -> Bool {
110+
if let concreteType = tryApply.concreteTypeOfDependentExistentialArchetype,
111+
tryApply.canReplaceExistentialArchetype()
112+
{
113+
let builder = Builder(before: tryApply, context)
114+
115+
builder.createTryApply(
116+
function: tryApply.callee,
117+
tryApply.replaceOpenedArchetypeInSubstituations(withConcreteType: concreteType, context),
118+
arguments: tryApply.replaceExistentialArchetypeInArguments(withConcreteType: concreteType, context),
119+
normalBlock: tryApply.normalBlock, errorBlock: tryApply.errorBlock,
120+
isNonAsync: tryApply.isNonAsync,
121+
specializationInfo: tryApply.specializationInfo)
122+
context.erase(instruction: tryApply)
123+
124+
return true
125+
}
126+
return false
127+
}
128+
129+
private extension FullApplySite {
130+
// Precondition: the apply uses only a single existential archetype.
131+
// This is checked in `concreteTypeOfDependentExistentialArchetype`
132+
func canReplaceExistentialArchetype() -> Bool {
133+
// Make sure that existential archetype _is_ a replacement type and not e.g. _contained_ in a
134+
// replacement type, like
135+
// apply %1<Array<@opened("...")>()
136+
guard substitutionMap.replacementTypes.contains(where: { $0.isExistentialArchetype }),
137+
substitutionMap.replacementTypes.allSatisfy({ $0.isExistentialArchetype || !$0.hasLocalArchetype })
138+
else {
139+
return false
140+
}
141+
142+
// Don't allow existential archetypes in direct results and error results.
143+
// Note that an opened existential value is address only, so it cannot be a direct result anyway
144+
// (but it can be once we have opaque values).
145+
// Also don't support things like direct `Array<@opened("...")>` return values.
146+
if let singleDirectResult, singleDirectResult.type.astType.hasLocalArchetype {
147+
return false
148+
}
149+
if let singleDirectErrorResult, singleDirectErrorResult.type.astType.hasLocalArchetype {
150+
return false
151+
}
152+
153+
return arguments.allSatisfy { value in
154+
let astTy = value.type.astType
155+
// Allow three cases:
156+
// case 1. the argument _is_ the existential archetype
157+
return astTy.isExistentialArchetype ||
158+
// case 2. the argument _is_ a metatype of the existential archetype
159+
(astTy.isMetatypeType && astTy.instanceTypeOfMetatype.isExistentialArchetype) ||
160+
// case 3. the argument has nothing to do with the existential archetype (or any other local archetype)
161+
!astTy.hasLocalArchetype
162+
}
163+
}
164+
165+
func replaceExistentialArchetypeInArguments(
166+
withConcreteType concreteType: CanonicalType,
167+
_ context: SimplifyContext
168+
) -> [Value] {
169+
let newArgs = arguments.map { (arg) -> Value in
170+
let argTy = arg.type.astType
171+
if argTy.isExistentialArchetype {
172+
// case 1. the argument _is_ the existential archetype:
173+
// just insert an address cast to satisfy type equivalence.
174+
let builder = Builder(before: self, context)
175+
let concreteSILType = concreteType.loweredType(in: self.parentFunction)
176+
return builder.createUncheckedAddrCast(from: arg, to: concreteSILType.addressType)
177+
}
178+
if argTy.isMetatypeType, argTy.instanceTypeOfMetatype.isExistentialArchetype {
179+
// case 2. the argument _is_ a metatype of the existential archetype:
180+
// re-create the metatype with the concrete type.
181+
let builder = Builder(before: self, context)
182+
return builder.createMetatype(ofInstanceType: concreteType, representation: argTy.representationOfMetatype)
183+
}
184+
// case 3. the argument has nothing to do with the existential archetype (or any other local archetype)
185+
return arg
186+
}
187+
return Array(newArgs)
188+
}
189+
190+
func replaceOpenedArchetypeInSubstituations(
191+
withConcreteType concreteType: CanonicalType,
192+
_ context: SimplifyContext
193+
) -> SubstitutionMap {
194+
let openedArcheType = substitutionMap.replacementTypes.first(where: { $0.isExistentialArchetype })!
195+
196+
let newReplacementTypes = substitutionMap.replacementTypes.map {
197+
return $0 == openedArcheType ? concreteType.type : $0
198+
}
199+
let genSig = callee.type.astType.invocationGenericSignatureOfFunctionType
200+
return SubstitutionMap(genericSignature: genSig, replacementTypes: newReplacementTypes)
201+
}
202+
}

SwiftCompilerSources/Sources/Optimizer/PassManager/PassRegistration.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ private func registerSwiftPasses() {
120120
registerForSILCombine(PointerToAddressInst.self, { run(PointerToAddressInst.self, $0) })
121121
registerForSILCombine(UncheckedEnumDataInst.self, { run(UncheckedEnumDataInst.self, $0) })
122122
registerForSILCombine(UnconditionalCheckedCastInst.self, { run(UnconditionalCheckedCastInst.self, $0) })
123+
registerForSILCombine(ApplyInst.self, { run(ApplyInst.self, $0) })
124+
registerForSILCombine(TryApplyInst.self, { run(TryApplyInst.self, $0) })
123125

124126
// Test passes
125127
registerPass(aliasInfoDumper, { aliasInfoDumper.run($0) })

include/swift/SILOptimizer/PassManager/Passes.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,8 @@ SWIFT_SILCOMBINE_PASS(PointerToAddressInst)
540540
SWIFT_SILCOMBINE_PASS(TypeValueInst)
541541
SWIFT_SILCOMBINE_PASS(UncheckedEnumDataInst)
542542
SWIFT_SILCOMBINE_PASS_WITH_LEGACY(UnconditionalCheckedCastInst)
543+
SWIFT_SILCOMBINE_PASS_WITH_LEGACY(ApplyInst)
544+
SWIFT_SILCOMBINE_PASS_WITH_LEGACY(TryApplyInst)
543545

544546
#undef IRGEN_PASS
545547
#undef SWIFT_MODULE_PASS

lib/SILOptimizer/SILCombiner/SILCombiner.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,7 @@ class SILCombiner :
244244

245245
/// Instruction visitors.
246246
SILInstruction *visitPartialApplyInst(PartialApplyInst *AI);
247-
SILInstruction *visitApplyInst(ApplyInst *AI);
248247
SILInstruction *visitBeginApplyInst(BeginApplyInst *BAI);
249-
SILInstruction *visitTryApplyInst(TryApplyInst *AI);
250248
SILInstruction *optimizeStringObject(BuiltinInst *BI);
251249
SILInstruction *visitBuiltinInst(BuiltinInst *BI);
252250
SILInstruction *visitCondFailInst(CondFailInst *CFI);

lib/SILOptimizer/SILCombiner/SILCombinerApplyVisitors.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,7 +1515,7 @@ static bool canBeRemovedIfResultIsNotUsed(SILFunction *f) {
15151515
return false;
15161516
}
15171517

1518-
SILInstruction *SILCombiner::visitApplyInst(ApplyInst *AI) {
1518+
SILInstruction *SILCombiner::legacyVisitApplyInst(ApplyInst *AI) {
15191519
Builder.setCurrentDebugScope(AI->getDebugScope());
15201520
// apply{partial_apply(x,y)}(z) -> apply(z,x,y) is triggered
15211521
// from visitPartialApplyInst(), so bail here.
@@ -1661,7 +1661,7 @@ isTryApplyResultNotUsed(UserListTy &AcceptedUses, TryApplyInst *TAI) {
16611661
return true;
16621662
}
16631663

1664-
SILInstruction *SILCombiner::visitTryApplyInst(TryApplyInst *AI) {
1664+
SILInstruction *SILCombiner::legacyVisitTryApplyInst(TryApplyInst *AI) {
16651665
// apply{partial_apply(x,y)}(z) -> apply(z,x,y) is triggered
16661666
// from visitPartialApplyInst(), so bail here.
16671667
if (isa<PartialApplyInst>(AI->getCallee()))

test/SILOptimizer/devirt_protocol_method_invocations.swift

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -140,9 +140,6 @@ public func test_devirt_protocol_extension_method_invocation_with_self_return_ty
140140
// CHECK: return [[T1]]
141141

142142
// CHECK: sil @$s34devirt_protocol_method_invocations14testExMetatypeSiyF
143-
// CHECK: [[T0:%.*]] = integer_literal
144-
// CHECK: [[T2:%.*]] = struct $Int ([[T0]] : {{.*}})
145-
// CHECK: return [[T2]] : $Int
146143

147144
@inline(never)
148145
public func test_devirt_protocol_method_invocation(_ c: C) -> Int {

test/SILOptimizer/devirt_witness_cross_module.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public struct Local: P {
4848

4949
// CHECK-LABEL: sil @$s4Main24testGenericInOtherModuleyyF
5050
// CHECK-NOCMO: [[F:%[0-9]+]] = witness_method $S, #P.foo
51-
// CHECK-CMO: [[F:%[0-9]+]] = function_ref @$s6Module1SV3foo1xyx_tSkRzSi7ElementRtzlFSaySiG_Ttgq5{{.*}}
51+
// CHECK-CMO: [[F:%[0-9]+]] = function_ref @$s6Module1SV3foo1xyx_tSkRzSi7ElementRtzlFSaySiG_Ttg{{.*}}
5252
// CHECK: apply [[F]]
5353
// CHECK: } // end sil function '$s4Main24testGenericInOtherModuleyyF'
5454
public func testGenericInOtherModule() {

test/SILOptimizer/sil_combine_apply.sil

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,8 +407,7 @@ sil @helperForOptimizeApplyOfConvertFunction : $@convention(thin) (@in Builtin.I
407407
// CHECK-LABEL: sil @testOptimizeApplyOfConvertFunction : $@convention(thin) (@in Builtin.Int8) -> @out Builtin.Int32 {
408408
// CHECK: bb0(%0 : $*Builtin.Int32, %1 : $*Builtin.Int8):
409409
// CHECK: [[FN:%.*]] = function_ref @helperForOptimizeApplyOfConvertFunction : $@convention(thin) (@in Builtin.Int8) -> @out Builtin.Int32
410-
// CHECK: [[TTF:%.*]] = thin_to_thick_function [[FN]] : $@convention(thin) (@in Builtin.Int8) -> @out Builtin.Int32 to $@noescape @callee_owned (@in Builtin.Int8) -> @out Builtin.Int32
411-
// CHECK: %{{.*}} = apply [[TTF]](%0, %1) : $@noescape @callee_owned (@in Builtin.Int8) -> @out Builtin.Int32
410+
// CHECK: %{{.*}} = apply [[FN]](%0, %1) : $@convention(thin) (@in Builtin.Int8) -> @out Builtin.Int32
412411
// CHECK: %{{.*}} = tuple ()
413412
// CHECK: return %{{.*}} : $()
414413
// CHECK-LABEL: } // end sil function 'testOptimizeApplyOfConvertFunction'

test/SILOptimizer/sil_combine_apply_ossa.sil

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -425,8 +425,7 @@ sil [ossa] @helperForOptimizeApplyOfConvertFunction : $@convention(thin) (@in Bu
425425
// CHECK-LABEL: sil [ossa] @testOptimizeApplyOfConvertFunction : $@convention(thin) (@in Builtin.Int8) -> @out Builtin.Int32 {
426426
// CHECK: bb0(%0 : $*Builtin.Int32, %1 : $*Builtin.Int8):
427427
// CHECK: [[FN:%.*]] = function_ref @helperForOptimizeApplyOfConvertFunction : $@convention(thin) (@in Builtin.Int8) -> @out Builtin.Int32
428-
// CHECK: [[TTF:%.*]] = thin_to_thick_function [[FN]] : $@convention(thin) (@in Builtin.Int8) -> @out Builtin.Int32 to $@noescape @callee_owned (@in Builtin.Int8) -> @out Builtin.Int32
429-
// CHECK: %{{.*}} = apply [[TTF]](%0, %1) : $@noescape @callee_owned (@in Builtin.Int8) -> @out Builtin.Int32
428+
// CHECK: %{{.*}} = apply [[FN]](%0, %1) : $@convention(thin) (@in Builtin.Int8) -> @out Builtin.Int32
430429
// CHECK: %{{.*}} = tuple ()
431430
// CHECK: return %{{.*}} : $()
432431
// CHECK-LABEL: } // end sil function 'testOptimizeApplyOfConvertFunction'

test/SILOptimizer/simplify_apply.sil

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %target-sil-opt -enable-sil-verify-all %s -onone-simplification -simplify-instruction=apply | %FileCheck %s
1+
// RUN: %target-sil-opt -enable-sil-verify-all %s -onone-simplification -simplify-instruction=apply | %FileCheck %s -check-prefix=CHECK -check-prefix=CHECKONONE
2+
// RUN: %target-sil-opt -enable-sil-verify-all %s -simplification -simplify-instruction=apply | %FileCheck %s -check-prefix=CHECK -check-prefix=CHECKO
23

34
// REQUIRES: swift_in_compiler
45

@@ -8,11 +9,23 @@ import Builtin
89
import Swift
910
import SwiftShims
1011

11-
class Bar {
12+
protocol P {}
13+
14+
class Bar: P {
1215
init()
1316
func foo() -> Int
1417
}
1518

19+
class Derived: Bar {}
20+
21+
struct S: P {
22+
var x: Int
23+
}
24+
25+
struct GenS<T> {
26+
var x: Int
27+
}
28+
1629
sil @cl : $@convention(thin) () -> Int
1730

1831
// CHECK-LABEL: sil [ossa] @thick_to_thin :
@@ -46,3 +59,83 @@ sil_vtable Bar {
4659
#Bar.foo: @bar_foo
4760
}
4861

62+
sil @createit : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type, Int) -> @out τ_0_0
63+
sil @useGenS : $@convention(thin) <τ_0_0 where τ_0_0 : P> (GenS<τ_0_0>) -> ()
64+
sil @returnGenS : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type) -> GenS<τ_0_0>
65+
66+
// CHECK-LABEL: sil [ossa] @replace_archetype :
67+
// CHECKO: [[E:%.*]] = init_existential_addr %0
68+
// CHECKO-DAG: [[C:%.*]] = unchecked_addr_cast [[E]] to $*S
69+
// CHECKO-DAG: [[M:%.*]] = metatype $@thick S.Type
70+
// CHECKO: = apply %{{[0-9]+}}<S>([[C]], [[M]], %1)
71+
// CHECKONONE: apply %{{[0-9]+}}<@opened
72+
// CHECK: } // end sil function 'replace_archetype'
73+
sil [ossa] @replace_archetype : $@convention(thin) (Int) -> @out any P {
74+
bb0(%0 : $*any P, %1 : $Int):
75+
%2 = metatype $@thick S.Type
76+
%3 = init_existential_metatype %2, $@thick any P.Type
77+
%4 = open_existential_metatype %3 to $@thick (@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self).Type
78+
%6 = function_ref @createit : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type, Int) -> @out τ_0_0
79+
%7 = init_existential_addr %0, $@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self
80+
%8 = apply %6<@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self>(%7, %4, %1) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type, Int) -> @out τ_0_0
81+
%11 = tuple ()
82+
return %11
83+
}
84+
85+
// CHECK-LABEL: sil [ossa] @dont_replace_archetype_unknown_concrete_type1 :
86+
// CHECK: apply %{{[0-9]+}}<@opened
87+
// CHECK: } // end sil function 'dont_replace_archetype_unknown_concrete_type1'
88+
sil [ossa] @dont_replace_archetype_unknown_concrete_type1 : $@convention(thin) (Int, @thick any P.Type) -> @out any P {
89+
bb0(%0 : $*any P, %1 : $Int, %2 : $@thick any P.Type):
90+
%4 = open_existential_metatype %2 to $@thick (@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self).Type
91+
%6 = function_ref @createit : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type, Int) -> @out τ_0_0
92+
%7 = init_existential_addr %0, $@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self
93+
%8 = apply %6<@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self>(%7, %4, %1) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type, Int) -> @out τ_0_0
94+
%11 = tuple ()
95+
return %11
96+
}
97+
98+
// CHECK-LABEL: sil [ossa] @dont_replace_archetype_unknown_concrete_type2 :
99+
// CHECK: apply %{{[0-9]+}}<@opened
100+
// CHECK: } // end sil function 'dont_replace_archetype_unknown_concrete_type2'
101+
sil [ossa] @dont_replace_archetype_unknown_concrete_type2 : $@convention(thin) (Int, @thick Bar.Type) -> @out any P {
102+
bb0(%0 : $*any P, %1 : $Int, %2 : $@thick Bar.Type):
103+
%3 = init_existential_metatype %2, $@thick any P.Type
104+
%4 = open_existential_metatype %3 to $@thick (@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self).Type
105+
%6 = function_ref @createit : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type, Int) -> @out τ_0_0
106+
%7 = init_existential_addr %0, $@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self
107+
%8 = apply %6<@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self>(%7, %4, %1) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type, Int) -> @out τ_0_0
108+
%11 = tuple ()
109+
return %11
110+
}
111+
112+
// CHECK-LABEL: sil [ossa] @dont_replace_embedded_archetype :
113+
// CHECK: apply %{{[0-9]+}}<@opened
114+
// CHECK: } // end sil function 'dont_replace_embedded_archetype'
115+
sil [ossa] @dont_replace_embedded_archetype : $@convention(thin) (Int) -> () {
116+
bb0(%0 : $Int):
117+
%2 = metatype $@thick S.Type
118+
%3 = init_existential_metatype %2, $@thick any P.Type
119+
%4 = open_existential_metatype %3 to $@thick (@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self).Type
120+
%5 = struct $GenS<@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self> (%0)
121+
%6 = function_ref @useGenS : $@convention(thin) <τ_0_0 where τ_0_0 : P> (GenS<τ_0_0>) -> ()
122+
%8 = apply %6<@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self>(%5) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (GenS<τ_0_0>) -> ()
123+
%11 = tuple ()
124+
return %11
125+
}
126+
127+
// CHECK-LABEL: sil [ossa] @dont_replace_returned_embedded_archetype :
128+
// CHECK: apply %{{[0-9]+}}<@opened
129+
// CHECK: } // end sil function 'dont_replace_returned_embedded_archetype'
130+
sil [ossa] @dont_replace_returned_embedded_archetype : $@convention(thin) (Int) -> () {
131+
bb0(%0 : $Int):
132+
%2 = metatype $@thick S.Type
133+
%3 = init_existential_metatype %2, $@thick any P.Type
134+
%4 = open_existential_metatype %3 to $@thick (@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self).Type
135+
%5 = struct $GenS<@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self> (%0)
136+
%6 = function_ref @returnGenS : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type) -> GenS<τ_0_0>
137+
%8 = apply %6<@opened("0FC03D78-E9DB-11EF-B47C-0EA13E3AABB3", any P) Self>(%4) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@thick τ_0_0.Type) -> GenS<τ_0_0>
138+
%11 = tuple ()
139+
return %11
140+
}
141+

0 commit comments

Comments
 (0)