Skip to content

Commit d6a5f21

Browse files
authored
Merge pull request swiftlang#29078 from slavapestov/vtable-thunk-reabstract-requirements-5.2
SILGen: Emit vtable thunks to re-abstract generic requirements [5.2]
2 parents 5e3a6ac + 4a10427 commit d6a5f21

File tree

7 files changed

+161
-57
lines changed

7 files changed

+161
-57
lines changed

include/swift/AST/SubstitutionMap.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,10 @@ enum class CombineSubstitutionMaps {
5252
/// any entity that can reference type parameters, e.g., types (via
5353
/// Type::subst()) and conformances (via ProtocolConformanceRef::subst()).
5454
///
55-
/// SubstitutionMaps are constructed by calling the getSubstitutionMap() method
56-
/// on a GenericSignature or (equivalently) by calling one of the static
57-
/// \c SubstitutionMap::get() methods. However, most substitution maps are
55+
/// SubstitutionMaps are constructed by calling the an overload of the static
56+
/// method \c SubstitutionMap::get(). However, most substitution maps are
5857
/// computed using higher-level entry points such as
59-
/// TypeBase::getMemberSubstitutionMap().
58+
/// TypeBase::getContextSubstitutionMap().
6059
///
6160
/// Substitution maps are ASTContext-allocated and are uniqued on construction,
6261
/// so they can be used as fields in AST nodes.

lib/AST/ASTContext.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4400,11 +4400,13 @@ ASTContext::getOverrideGenericSignature(const ValueDecl *base,
44004400
const ValueDecl *derived) {
44014401
auto baseGenericCtx = base->getAsGenericContext();
44024402
auto derivedGenericCtx = derived->getAsGenericContext();
4403-
auto &ctx = base->getASTContext();
44044403

44054404
if (!baseGenericCtx || !derivedGenericCtx)
44064405
return nullptr;
44074406

4407+
if (base == derived)
4408+
return derivedGenericCtx->getGenericSignature();
4409+
44084410
auto baseClass = base->getDeclContext()->getSelfClassDecl();
44094411
if (!baseClass)
44104412
return nullptr;
@@ -4460,7 +4462,7 @@ ASTContext::getOverrideGenericSignature(const ValueDecl *base,
44604462
}
44614463

44624464
return CanGenericTypeParamType::get(
4463-
gp->getDepth() - baseDepth + derivedDepth, gp->getIndex(), ctx);
4465+
gp->getDepth() - baseDepth + derivedDepth, gp->getIndex(), *this);
44644466
};
44654467

44664468
auto lookupConformanceFn =
@@ -4480,7 +4482,7 @@ ASTContext::getOverrideGenericSignature(const ValueDecl *base,
44804482
}
44814483

44824484
auto genericSig = evaluateOrDefault(
4483-
ctx.evaluator,
4485+
evaluator,
44844486
AbstractGenericSignatureRequest{
44854487
derivedClass->getGenericSignature().getPointer(),
44864488
std::move(addedGenericParams),

lib/SIL/SILFunctionType.cpp

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2514,64 +2514,77 @@ TypeConverter::getConstantOverrideInfo(TypeExpansionContext context,
25142514

25152515
assert(base.requiresNewVTableEntry() && "base must not be an override");
25162516

2517+
// Figure out the generic signature for the class method call. This is the
2518+
// signature of the derived class, with requirements transplanted from
2519+
// the base method. The derived method is allowed to have fewer
2520+
// requirements, in which case the thunk will translate the calling
2521+
// convention appropriately before calling the derived method.
2522+
bool hasGenericRequirementDifference = false;
2523+
2524+
auto derivedSig = derived.getDecl()->getAsGenericContext()
2525+
->getGenericSignature();
2526+
auto genericSig = Context.getOverrideGenericSignature(base.getDecl(),
2527+
derived.getDecl());
2528+
if (genericSig) {
2529+
hasGenericRequirementDifference =
2530+
!genericSig->requirementsNotSatisfiedBy(derivedSig).empty();
2531+
}
2532+
25172533
auto baseInfo = getConstantInfo(context, base);
25182534
auto derivedInfo = getConstantInfo(context, derived);
25192535

2520-
// If the derived method is ABI-compatible with the base method, give the
2521-
// vtable thunk the same signature as the derived method.
2522-
auto basePattern = AbstractionPattern(baseInfo.LoweredType);
2523-
2524-
auto baseInterfaceTy = baseInfo.FormalType;
2525-
auto derivedInterfaceTy = derivedInfo.FormalType;
2526-
2527-
auto params = derivedInterfaceTy.getParams();
2536+
auto params = derivedInfo.FormalType.getParams();
25282537
assert(params.size() == 1);
25292538
auto selfInterfaceTy = params[0].getPlainType()->getMetatypeInstanceType();
25302539

25312540
auto overrideInterfaceTy =
2541+
cast<AnyFunctionType>(
25322542
selfInterfaceTy->adjustSuperclassMemberDeclType(
2533-
base.getDecl(), derived.getDecl(), baseInterfaceTy);
2534-
2535-
// Copy generic signature from derived to the override type, to handle
2536-
// the case where the base member is not generic (because the base class
2537-
// is concrete) but the derived member is generic (because the derived
2538-
// class is generic).
2539-
if (auto derivedInterfaceFnTy = derivedInterfaceTy->getAs<GenericFunctionType>()) {
2540-
auto overrideInterfaceFnTy = overrideInterfaceTy->castTo<FunctionType>();
2541-
overrideInterfaceTy =
2542-
GenericFunctionType::get(derivedInterfaceFnTy->getGenericSignature(),
2543-
overrideInterfaceFnTy->getParams(),
2544-
overrideInterfaceFnTy->getResult(),
2545-
overrideInterfaceFnTy->getExtInfo());
2546-
}
2543+
base.getDecl(), derived.getDecl(), baseInfo.FormalType)
2544+
->getCanonicalType());
25472545

2548-
// Lower the formal AST type.
2549-
auto bridgedTypes = getLoweredFormalTypes(derived,
2550-
cast<AnyFunctionType>(overrideInterfaceTy->getCanonicalType()));
2551-
auto overrideLoweredInterfaceTy = bridgedTypes.Uncurried;
2546+
// Build the formal AST function type for the class method call.
2547+
auto basePattern = AbstractionPattern(baseInfo.LoweredType);
2548+
2549+
if (!hasGenericRequirementDifference &&
2550+
!checkASTTypeForABIDifferences(derivedInfo.FormalType,
2551+
overrideInterfaceTy)) {
25522552

2553-
if (!checkASTTypeForABIDifferences(derivedInfo.LoweredType,
2554-
overrideLoweredInterfaceTy)) {
2553+
// The derived method is ABI-compatible with the base method. Let's
2554+
// just use the derived method's formal type.
25552555
basePattern = AbstractionPattern(
25562556
copyOptionalityFromDerivedToBase(
25572557
*this,
25582558
derivedInfo.LoweredType,
25592559
baseInfo.LoweredType));
2560-
overrideLoweredInterfaceTy = derivedInfo.LoweredType;
2560+
overrideInterfaceTy = derivedInfo.FormalType;
2561+
}
2562+
2563+
if (genericSig && !genericSig->areAllParamsConcrete()) {
2564+
overrideInterfaceTy =
2565+
cast<AnyFunctionType>(
2566+
GenericFunctionType::get(genericSig,
2567+
overrideInterfaceTy->getParams(),
2568+
overrideInterfaceTy->getResult(),
2569+
overrideInterfaceTy->getExtInfo())
2570+
->getCanonicalType());
25612571
}
25622572

2563-
// Build the SILFunctionType for the vtable thunk.
2573+
// Build the lowered AST function type for the class method call.
2574+
auto bridgedTypes = getLoweredFormalTypes(derived, overrideInterfaceTy);
2575+
2576+
// Build the SILFunctionType for the class method call.
25642577
CanSILFunctionType fnTy = getNativeSILFunctionType(
2565-
*this, context, basePattern, overrideLoweredInterfaceTy, base, derived,
2578+
*this, context, basePattern, bridgedTypes.Uncurried, base, derived,
25662579
/*reqt subs*/ None, ProtocolConformanceRef());
25672580

25682581
// Build the SILConstantInfo and cache it.
25692582
auto resultBuf = Context.Allocate(sizeof(SILConstantInfo),
25702583
alignof(SILConstantInfo));
25712584
auto result = ::new (resultBuf) SILConstantInfo{
2572-
derivedInterfaceTy,
2573-
bridgedTypes.Pattern,
2574-
overrideLoweredInterfaceTy,
2585+
overrideInterfaceTy,
2586+
basePattern,
2587+
bridgedTypes.Uncurried,
25752588
fnTy};
25762589

25772590
auto inserted = ConstantOverrideTypes.insert({{derived, base}, result});

lib/SILGen/SILGenPoly.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3602,10 +3602,10 @@ SILGenFunction::emitVTableThunk(SILDeclRef base,
36023602
SGM.Types.getConstantInfo(getTypeExpansionContext(), derived).SILFnType;
36033603
}
36043604

3605-
SubstitutionMap subs;
3606-
if (auto *genericEnv = fd->getGenericEnvironment()) {
3607-
F.setGenericEnvironment(genericEnv);
3608-
subs = getForwardingSubstitutionMap();
3605+
auto subs = getForwardingSubstitutionMap();
3606+
if (auto genericSig = derivedFTy->getSubstGenericSignature()) {
3607+
subs = SubstitutionMap::get(derivedFTy->getSubstGenericSignature(), subs);
3608+
36093609
derivedFTy =
36103610
derivedFTy->substGenericArgs(SGM.M, subs, getTypeExpansionContext());
36113611

lib/SILGen/SILGenType.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,16 @@ SILGenModule::emitVTableMethod(ClassDecl *theClass,
165165
if (auto existingThunk = M.lookUpFunction(name))
166166
return SILVTable::Entry(base, existingThunk, implKind);
167167

168+
GenericEnvironment *genericEnv = nullptr;
169+
if (auto genericSig = overrideInfo.FormalType.getOptGenericSignature())
170+
genericEnv = genericSig->getGenericEnvironment();
171+
168172
// Emit the thunk.
169173
SILLocation loc(derivedDecl);
170174
SILGenFunctionBuilder builder(*this);
171175
auto thunk = builder.createFunction(
172176
SILLinkage::Private, name, overrideInfo.SILFnType,
173-
cast<AbstractFunctionDecl>(derivedDecl)->getGenericEnvironment(), loc,
177+
genericEnv, loc,
174178
IsBare, IsNotTransparent, IsNotSerialized, IsNotDynamic,
175179
ProfileCounter(), IsThunk);
176180
thunk->setDebugScope(new (M) SILDebugScope(loc, thunk));
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
2+
// RUN: %target-swift-emit-ir %s
3+
4+
protocol P {}
5+
protocol Q : P {}
6+
7+
class ConcreteBase {
8+
func f<U : Q>(_: U) {}
9+
}
10+
11+
class ConcreteDerivedFromConcreteBase : ConcreteBase {
12+
override func f<U : P>(_: U) {}
13+
}
14+
15+
class GenericDerivedFromConcreteBase<T> : ConcreteBase {
16+
override func f<U : P>(_: U) {}
17+
}
18+
19+
class GenericBase<T> {
20+
func f<U : Q>(_: U) {}
21+
}
22+
23+
class ConcreteDerivedFromGenericBase : GenericBase<Int> {
24+
override func f<U : P>(_: U) {}
25+
}
26+
27+
class GenericDerivedFromGenericBase<T> : GenericBase<(T) -> Int> {
28+
override func f<U : P>(_: U) {}
29+
}
30+
31+
// Make sure we call these methods with the correct substitution map.
32+
func call<T, U : P>(_ t: T, _ u: U) {
33+
ConcreteDerivedFromConcreteBase().f(u)
34+
GenericDerivedFromConcreteBase<T>().f(u)
35+
36+
ConcreteDerivedFromGenericBase().f(u)
37+
GenericDerivedFromGenericBase<T>().f(u)
38+
}
39+
40+
// All the vtable thunks should traffic in <U where U : Q>, because that's
41+
// what the base method declares.
42+
43+
// CHECK-LABEL: sil private [thunk] [ossa] @$s24vtable_generic_signature019ConcreteDerivedFromD4BaseC1fyyxAA1PRzlFAA0dG0CADyyxAA1QRzlFTV : $@convention(method) <τ_0_0 where τ_0_0 : Q> (@in_guaranteed τ_0_0, @guaranteed ConcreteDerivedFromConcreteBase) -> ()
44+
// CHECK-LABEL: sil private [thunk] [ossa] @$s24vtable_generic_signature30GenericDerivedFromConcreteBaseC1fyyqd__AA1PRd__lFAA0gH0CADyyxAA1QRzlFTV : $@convention(method) <τ_0_0><τ_1_0 where τ_1_0 : Q> (@in_guaranteed τ_1_0, @guaranteed GenericDerivedFromConcreteBase<τ_0_0>) -> ()
45+
// CHECK-LABEL: sil private [thunk] [ossa] @$s24vtable_generic_signature30ConcreteDerivedFromGenericBaseC1fyyxAA1PRzlFAA0gH0CADyyqd__AA1QRd__lFTV : $@convention(method) <τ_0_0 where τ_0_0 : Q> (@in_guaranteed τ_0_0, @guaranteed ConcreteDerivedFromGenericBase) -> ()
46+
// CHECK-LABEL: sil private [thunk] [ossa] @$s24vtable_generic_signature018GenericDerivedFromD4BaseC1fyyqd__AA1PRd__lFAA0dG0CADyyqd__AA1QRd__lFTV : $@convention(method) <τ_0_0><τ_1_0 where τ_1_0 : Q> (@in_guaranteed τ_1_0, @guaranteed GenericDerivedFromGenericBase<τ_0_0>) -> ()
47+
48+
// CHECK-LABEL: sil_vtable ConcreteBase {
49+
// CHECK-NEXT: #ConcreteBase.f!1: <U where U : Q> (ConcreteBase) -> (U) -> () : @$s24vtable_generic_signature12ConcreteBaseC1fyyxAA1QRzlF
50+
// CHECK-NEXT: #ConcreteBase.init!allocator.1: (ConcreteBase.Type) -> () -> ConcreteBase : @$s24vtable_generic_signature12ConcreteBaseCACycfC
51+
// CHECK-NEXT: #ConcreteBase.deinit!deallocator.1: @$s24vtable_generic_signature12ConcreteBaseCfD
52+
// CHECK-NEXT: }
53+
54+
// CHECK-LABEL: sil_vtable ConcreteDerivedFromConcreteBase {
55+
// CHECK-NEXT: #ConcreteBase.f!1: <U where U : Q> (ConcreteBase) -> (U) -> () : @$s24vtable_generic_signature019ConcreteDerivedFromD4BaseC1fyyxAA1PRzlFAA0dG0CADyyxAA1QRzlFTV [override]
56+
// CHECK-NEXT: #ConcreteBase.init!allocator.1: (ConcreteBase.Type) -> () -> ConcreteBase : @$s24vtable_generic_signature019ConcreteDerivedFromD4BaseCACycfC [override]
57+
// CHECK-NEXT: #ConcreteDerivedFromConcreteBase.f!1: <U where U : P> (ConcreteDerivedFromConcreteBase) -> (U) -> () : @$s24vtable_generic_signature019ConcreteDerivedFromD4BaseC1fyyxAA1PRzlF
58+
// CHECK-NEXT: #ConcreteDerivedFromConcreteBase.deinit!deallocator.1: @$s24vtable_generic_signature019ConcreteDerivedFromD4BaseCfD
59+
// CHECK-NEXT: }
60+
61+
// CHECK-LABEL: sil_vtable GenericDerivedFromConcreteBase {
62+
// CHECK-NEXT: #ConcreteBase.f!1: <U where U : Q> (ConcreteBase) -> (U) -> () : @$s24vtable_generic_signature30GenericDerivedFromConcreteBaseC1fyyqd__AA1PRd__lFAA0gH0CADyyxAA1QRzlFTV [override]
63+
// CHECK-NEXT: #ConcreteBase.init!allocator.1: (ConcreteBase.Type) -> () -> ConcreteBase : @$s24vtable_generic_signature30GenericDerivedFromConcreteBaseCACyxGycfC [override]
64+
// CHECK-NEXT: #GenericDerivedFromConcreteBase.f!1: <T><U where U : P> (GenericDerivedFromConcreteBase<T>) -> (U) -> () : @$s24vtable_generic_signature30GenericDerivedFromConcreteBaseC1fyyqd__AA1PRd__lF
65+
// CHECK-NEXT: #GenericDerivedFromConcreteBase.deinit!deallocator.1: @$s24vtable_generic_signature30GenericDerivedFromConcreteBaseCfD
66+
// CHECK-NEXT: }
67+
68+
// CHECK-LABEL: sil_vtable GenericBase {
69+
// CHECK-NEXT: #GenericBase.f!1: <T><U where U : Q> (GenericBase<T>) -> (U) -> () : @$s24vtable_generic_signature11GenericBaseC1fyyqd__AA1QRd__lF
70+
// CHECK-NEXT: #GenericBase.init!allocator.1: <T> (GenericBase<T>.Type) -> () -> GenericBase<T> : @$s24vtable_generic_signature11GenericBaseCACyxGycfC
71+
// CHECK-NEXT: #GenericBase.deinit!deallocator.1: @$s24vtable_generic_signature11GenericBaseCfD
72+
// CHECK-NEXT: }
73+
74+
// CHECK-LABEL: sil_vtable ConcreteDerivedFromGenericBase {
75+
// CHECK-NEXT: #GenericBase.f!1: <T><U where U : Q> (GenericBase<T>) -> (U) -> () : @$s24vtable_generic_signature30ConcreteDerivedFromGenericBaseC1fyyxAA1PRzlFAA0gH0CADyyqd__AA1QRd__lFTV [override]
76+
// CHECK-NEXT: #GenericBase.init!allocator.1: <T> (GenericBase<T>.Type) -> () -> GenericBase<T> : @$s24vtable_generic_signature30ConcreteDerivedFromGenericBaseCACycfC [override]
77+
// CHECK-NEXT: #ConcreteDerivedFromGenericBase.f!1: <U where U : P> (ConcreteDerivedFromGenericBase) -> (U) -> () : @$s24vtable_generic_signature30ConcreteDerivedFromGenericBaseC1fyyxAA1PRzlF
78+
// CHECK-NEXT: #ConcreteDerivedFromGenericBase.deinit!deallocator.1: @$s24vtable_generic_signature30ConcreteDerivedFromGenericBaseCfD
79+
// CHECK-NEXT: }
80+
81+
// CHECK-LABEL: sil_vtable GenericDerivedFromGenericBase {
82+
// CHECK-NEXT: #GenericBase.f!1: <T><U where U : Q> (GenericBase<T>) -> (U) -> () : @$s24vtable_generic_signature018GenericDerivedFromD4BaseC1fyyqd__AA1PRd__lFAA0dG0CADyyqd__AA1QRd__lFTV [override]
83+
// CHECK-NEXT: #GenericBase.init!allocator.1: <T> (GenericBase<T>.Type) -> () -> GenericBase<T> : @$s24vtable_generic_signature018GenericDerivedFromD4BaseCACyxGycfC [override]
84+
// CHECK-NEXT: #GenericDerivedFromGenericBase.f!1: <T><U where U : P> (GenericDerivedFromGenericBase<T>) -> (U) -> () : @$s24vtable_generic_signature018GenericDerivedFromD4BaseC1fyyqd__AA1PRd__lF
85+
// CHECK-NEXT: #GenericDerivedFromGenericBase.deinit!deallocator.1: @$s24vtable_generic_signature018GenericDerivedFromD4BaseCfD
86+
// CHECK-NEXT: }

test/SILGen/vtable_thunks_reabstraction_modify.swift

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,21 @@ public class DerivedClass<Result> : BaseClass<Int, Result> {
1515
}
1616
}
1717

18-
// CHECK-LABEL: sil private [thunk] [ossa] @$s34vtable_thunks_reabstraction_modify12DerivedClassC8callbackyxSicvMAA04BaseF0CADyq_xcvMTV : $@yield_once @convention(method) <Result> (@guaranteed DerivedClass<Result>) -> @yields @inout @callee_guaranteed (@in_guaranteed Int) -> @out Result {
18+
// CHECK-LABEL: sil private [thunk] [ossa] @$s34vtable_thunks_reabstraction_modify12DerivedClassC8callbackyxSicvMAA04BaseF0CADyq_xcvMTV : $@yield_once @convention(method) <τ_0_0> (@guaranteed DerivedClass<τ_0_0>) -> @yields @inout @callee_guaranteed (@in_guaranteed Int) -> @out τ_0_0 {
1919
// CHECK: [[DERIVED:%.*]] = function_ref @$s34vtable_thunks_reabstraction_modify12DerivedClassC8callbackyxSicvM : $@yield_once @convention(method) <τ_0_0> (@guaranteed DerivedClass<τ_0_0>) -> @yields @inout @callee_guaranteed (Int) -> @out τ_0_0
20-
// CHECK: ([[RESULT_BUF:%.*]], [[TOKEN:%.*]]) = begin_apply [[DERIVED]]<Result>(%0) : $@yield_once @convention(method) <τ_0_0> (@guaranteed DerivedClass<τ_0_0>) -> @yields @inout @callee_guaranteed (Int) -> @out τ_0_0
21-
// CHECK: [[OUTER_RESULT_BUF:%.*]] = alloc_stack $@callee_guaranteed (@in_guaranteed Int) -> @out Result
22-
// CHECK: [[RESULT:%.*]] = load [take] [[RESULT_BUF]] : $*@callee_guaranteed (Int) -> @out Result
20+
// CHECK: ([[RESULT_BUF:%.*]], [[TOKEN:%.*]]) = begin_apply [[DERIVED]]<τ_0_0>(%0) : $@yield_once @convention(method) <τ_0_0> (@guaranteed DerivedClass<τ_0_0>) -> @yields @inout @callee_guaranteed (Int) -> @out τ_0_0
21+
// CHECK: [[OUTER_RESULT_BUF:%.*]] = alloc_stack $@callee_guaranteed (@in_guaranteed Int) -> @out τ_0_0
22+
// CHECK: [[RESULT:%.*]] = load [take] [[RESULT_BUF]] : $*@callee_guaranteed (Int) -> @out τ_0_0
2323
// CHECK: [[THUNK_FN:%.*]] = function_ref @$sSixIegyr_SixIegnr_lTR : $@convention(thin) <τ_0_0> (@in_guaranteed Int, @guaranteed @callee_guaranteed (Int) -> @out τ_0_0) -> @out τ_0_0
24-
// CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<Result>([[RESULT]]) : $@convention(thin) <τ_0_0> (@in_guaranteed Int, @guaranteed @callee_guaranteed (Int) -> @out τ_0_0) -> @out τ_0_0
25-
// CHECK: store [[THUNK]] to [init] [[OUTER_RESULT_BUF]] : $*@callee_guaranteed (@in_guaranteed Int) -> @out Result
26-
// CHECK: yield [[OUTER_RESULT_BUF]] : $*@callee_guaranteed (@in_guaranteed Int) -> @out Result, resume bb1, unwind bb2
24+
// CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<τ_0_0>([[RESULT]]) : $@convention(thin) <τ_0_0> (@in_guaranteed Int, @guaranteed @callee_guaranteed (Int) -> @out τ_0_0) -> @out τ_0_0
25+
// CHECK: store [[THUNK]] to [init] [[OUTER_RESULT_BUF]] : $*@callee_guaranteed (@in_guaranteed Int) -> @out τ_0_0
26+
// CHECK: yield [[OUTER_RESULT_BUF]] : $*@callee_guaranteed (@in_guaranteed Int) -> @out τ_0_0, resume bb1, unwind bb2
2727

2828
// CHECK: bb1:
29-
// CHECK: [[MODIFIED:%.*]] = load [take] [[OUTER_RESULT_BUF]] : $*@callee_guaranteed (@in_guaranteed Int) -> @out Result
29+
// CHECK: [[MODIFIED:%.*]] = load [take] [[OUTER_RESULT_BUF]] : $*@callee_guaranteed (@in_guaranteed Int) -> @out τ_0_0
3030
// CHECK: [[THUNK_FN:%.*]] = function_ref @$sSixIegnr_SixIegyr_lTR : $@convention(thin) <τ_0_0> (Int, @guaranteed @callee_guaranteed (@in_guaranteed Int) -> @out τ_0_0) -> @out τ_0_0
31-
// CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<Result>([[MODIFIED]]) : $@convention(thin) <τ_0_0> (Int, @guaranteed @callee_guaranteed (@in_guaranteed Int) -> @out τ_0_0) -> @out τ_0_0
32-
// CHECK: store [[THUNK]] to [init] [[RESULT_BUF]] : $*@callee_guaranteed (Int) -> @out Result
33-
// CHECK: dealloc_stack [[OUTER_RESULT_BUF]] : $*@callee_guaranteed (@in_guaranteed Int) -> @out Result
31+
// CHECK: [[THUNK:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FN]]<τ_0_0>([[MODIFIED]]) : $@convention(thin) <τ_0_0> (Int, @guaranteed @callee_guaranteed (@in_guaranteed Int) -> @out τ_0_0) -> @out τ_0_0
32+
// CHECK: store [[THUNK]] to [init] [[RESULT_BUF]] : $*@callee_guaranteed (Int) -> @out τ_0_0
33+
// CHECK: dealloc_stack [[OUTER_RESULT_BUF]] : $*@callee_guaranteed (@in_guaranteed Int) -> @out τ_0_0
3434
// CHECK: end_apply [[TOKEN]]
3535
// CHECK: return

0 commit comments

Comments
 (0)