Skip to content

Commit 377d22e

Browse files
committed
SILGen: Use the correct generic environment in vtable thunks
Make sure we use the generic environment derived from the generic signature of the vtable thunk itself, which can now be different than the generic signature of the derived method. This allows vtable thunks that re-abstract generic requirements to lower all the way through to IRGen.
1 parent 2d670f4 commit 377d22e

File tree

4 files changed

+34
-20
lines changed

4 files changed

+34
-20
lines changed

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(genericSig, 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));

test/SILGen/vtable_generic_signature.swift

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
2+
// RUN: %target-swift-emit-ir %s
23

34
protocol P {}
45
protocol Q : P {}
@@ -27,13 +28,22 @@ class GenericDerivedFromGenericBase<T> : GenericBase<(T) -> Int> {
2728
override func f<U : P>(_: U) {}
2829
}
2930

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+
3040
// All the vtable thunks should traffic in <U where U : Q>, because that's
3141
// what the base method declares.
3242

33-
// CHECK-LABEL: sil private [thunk] [ossa] @$s24vtable_generic_signature019ConcreteDerivedFromD4BaseC1fyyxAA1PRzlFAA0dG0CADyyxAA1QRzlFTV : $@convention(method) <U where U : Q> (@in_guaranteed U, @guaranteed ConcreteDerivedFromConcreteBase) -> ()
34-
// CHECK-LABEL: sil private [thunk] [ossa] @$s24vtable_generic_signature30GenericDerivedFromConcreteBaseC1fyyqd__AA1PRd__lFAA0gH0CADyyxAA1QRzlFTV : $@convention(method) <T><U where U : Q> (@in_guaranteed U, @guaranteed GenericDerivedFromConcreteBase<T>) -> ()
35-
// CHECK-LABEL: sil private [thunk] [ossa] @$s24vtable_generic_signature30ConcreteDerivedFromGenericBaseC1fyyxAA1PRzlFAA0gH0CADyyqd__AA1QRd__lFTV : $@convention(method) <U where U : Q> (@in_guaranteed U, @guaranteed ConcreteDerivedFromGenericBase) -> ()
36-
// CHECK-LABEL: sil private [thunk] [ossa] @$s24vtable_generic_signature018GenericDerivedFromD4BaseC1fyyqd__AA1PRd__lFAA0dG0CADyyqd__AA1QRd__lFTV : $@convention(method) <T><U where U : Q> (@in_guaranteed U, @guaranteed GenericDerivedFromGenericBase<T>) -> ()
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>) -> ()
3747

3848
// CHECK-LABEL: sil_vtable ConcreteBase {
3949
// CHECK-NEXT: #ConcreteBase.f!1: <U where U : Q> (ConcreteBase) -> (U) -> () : @$s24vtable_generic_signature12ConcreteBaseC1fyyxAA1QRzlF

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)