Skip to content

Commit 099bd8e

Browse files
committed
SILGen: Fix withoutActuallyEscaping for DynamicSelfType
We can reuse the same logic that we have for reabstraction thunks here.
1 parent 4093d5e commit 099bd8e

File tree

3 files changed

+38
-30
lines changed

3 files changed

+38
-30
lines changed

lib/SILGen/SILGenPoly.cpp

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3228,23 +3228,22 @@ static ManagedValue createThunk(SILGenFunction &SGF,
32283228
static CanSILFunctionType buildWithoutActuallyEscapingThunkType(
32293229
SILGenFunction &SGF, CanSILFunctionType &noEscapingType,
32303230
CanSILFunctionType &escapingType, GenericEnvironment *&genericEnv,
3231-
SubstitutionMap &interfaceSubs) {
3231+
SubstitutionMap &interfaceSubs, CanType &dynamicSelfType) {
32323232

32333233
assert(escapingType->getExtInfo() ==
32343234
noEscapingType->getExtInfo().withNoEscape(false));
32353235

32363236
CanType inputSubstType, outputSubstType;
3237-
CanType dynamicSelfType;
32383237
auto type = SGF.buildThunkType(noEscapingType, escapingType,
32393238
inputSubstType, outputSubstType,
32403239
genericEnv, interfaceSubs,
32413240
dynamicSelfType,
32423241
/*withoutActuallyEscaping=*/true);
3243-
assert(!dynamicSelfType && "not implemented");
32443242
return type;
32453243
}
32463244

3247-
static void buildWithoutActuallyEscapingThunkBody(SILGenFunction &SGF) {
3245+
static void buildWithoutActuallyEscapingThunkBody(SILGenFunction &SGF,
3246+
CanType dynamicSelfType) {
32483247
PrettyStackTraceSILFunction stackTrace(
32493248
"emitting withoutAcutallyEscaping thunk in", &SGF.F);
32503249

@@ -3256,6 +3255,11 @@ static void buildWithoutActuallyEscapingThunkBody(SILGenFunction &SGF) {
32563255
SmallVector<SILArgument*, 8> indirectResults;
32573256
SGF.collectThunkParams(loc, params, &indirectResults);
32583257

3258+
// Ignore the self parameter at the SIL level. IRGen will use it to
3259+
// recover type metadata.
3260+
if (dynamicSelfType)
3261+
params.pop_back();
3262+
32593263
ManagedValue fnValue = params.pop_back_val();
32603264
auto fnType = fnValue.getType().castTo<SILFunctionType>();
32613265

@@ -3297,47 +3301,37 @@ SILGenFunction::createWithoutActuallyEscapingClosure(
32973301
auto noEscapingFnTy =
32983302
noEscapingFunctionValue.getType().castTo<SILFunctionType>();
32993303

3304+
CanType dynamicSelfType;
33003305
auto thunkType = buildWithoutActuallyEscapingThunkType(
3301-
*this, noEscapingFnTy, escapingFnTy, genericEnv, interfaceSubs);
3306+
*this, noEscapingFnTy, escapingFnTy, genericEnv, interfaceSubs,
3307+
dynamicSelfType);
33023308

33033309
auto *thunk = SGM.getOrCreateReabstractionThunk(
3304-
thunkType, noEscapingFnTy, escapingFnTy,
3305-
/*dynamicSelfType=*/CanType());
3310+
thunkType, noEscapingFnTy, escapingFnTy, dynamicSelfType);
33063311

33073312
if (thunk->empty()) {
33083313
thunk->setWithoutActuallyEscapingThunk();
33093314
thunk->setGenericEnvironment(genericEnv);
33103315
SILGenFunction thunkSGF(SGM, *thunk, FunctionDC);
3311-
buildWithoutActuallyEscapingThunkBody(thunkSGF);
3316+
buildWithoutActuallyEscapingThunkBody(thunkSGF, dynamicSelfType);
33123317
}
33133318
assert(thunk->isWithoutActuallyEscapingThunk());
33143319

3315-
CanSILFunctionType substFnTy = thunkType;
3316-
// Use the subsitution map in the context of the current function.
3317-
// thunk->getForwardingSubstitutionMap() / thunk might have been created in a
3318-
// different function's generic enviroment.
3319-
if (thunkType->getGenericSignature()) {
3320-
substFnTy = thunkType->substGenericArgs(F.getModule(), interfaceSubs);
3321-
}
3322-
3323-
// Create it in our current function.
3324-
auto thunkValue = B.createFunctionRefFor(loc, thunk);
3325-
33263320
// Create a copy for the noescape value, so we can mark_dependence upon the
33273321
// original value.
3328-
SILValue noEscapeValue =
3329-
noEscapingFunctionValue.copy(*this, loc).forward(*this);
3330-
SingleValueInstruction *thunkedFn = B.createPartialApply(
3331-
loc, thunkValue,
3332-
SILType::getPrimitiveObjectType(substFnTy),
3333-
interfaceSubs,
3334-
noEscapeValue,
3335-
SILType::getPrimitiveObjectType(escapingFnTy));
3322+
auto noEscapeValue = noEscapingFunctionValue.copy(*this, loc);
3323+
3324+
auto thunkedFn =
3325+
createPartialApplyOfThunk(*this, loc, thunk, interfaceSubs, dynamicSelfType,
3326+
escapingFnTy, noEscapeValue);
3327+
33363328
// We need to ensure the 'lifetime' of the trivial values context captures. As
33373329
// long as we represent these captures by the same value the following works.
3338-
thunkedFn = B.createMarkDependence(loc, thunkedFn, noEscapingFunctionValue.getValue());
3330+
thunkedFn = emitManagedRValueWithCleanup(
3331+
B.createMarkDependence(loc, thunkedFn.forward(*this),
3332+
noEscapingFunctionValue.getValue()));
33393333

3340-
return emitManagedRValueWithCleanup(thunkedFn);
3334+
return thunkedFn;
33413335
}
33423336

33433337
ManagedValue Transform::transformFunction(ManagedValue fn,

test/SILGen/dynamic_self.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,8 @@ public extension EmptyProtocol {
420420
func run(_: (Self) -> ()) { }
421421
}
422422

423+
func doEscaping<T>(_: @escaping (T) -> ()) {}
424+
423425
public class FunctionConversionTest : EmptyProtocol {
424426
// CHECK-LABEL: sil hidden [ossa] @$s12dynamic_self22FunctionConversionTestC07convertC0yACXDyypXEF : $@convention(method) (@noescape @callee_guaranteed (@in_guaranteed Any) -> (), @guaranteed FunctionConversionTest) -> @owned FunctionConversionTest {
425427
func convertFunction(_ fn: (Any) -> ()) -> Self {
@@ -428,6 +430,18 @@ public class FunctionConversionTest : EmptyProtocol {
428430
run(fn)
429431
return self
430432
}
433+
434+
func convertWithoutEscaping(_ fn: (Any.Type) -> ()) -> Self {
435+
func takesNoEscapeWithSelf(_ _fn: (Self.Type) -> ()) {
436+
withoutActuallyEscaping(_fn) { __fn in
437+
doEscaping(__fn)
438+
}
439+
}
440+
441+
takesNoEscapeWithSelf(fn)
442+
443+
return self
444+
}
431445
}
432446

433447
// CHECK-LABEL: sil_witness_table hidden X: P module dynamic_self {

test/SILGen/without_actually_escaping.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ func modifyAndPerform<T>(_ _: UnsafeMutablePointer<T>, closure: () ->()) {
8686
// CHECK: [[CLOSURE_1:%.*]] = partial_apply [callee_guaranteed] [[CLOSURE_1_FUN]](
8787
// CHECK: [[BORROWED_CLOSURE_1:%.*]] = begin_borrow [[CLOSURE_1]]
8888
// CHECK: [[COPY_BORROWED_CLOSURE_1:%.*]] = copy_value [[BORROWED_CLOSURE_1]]
89-
// CHECK: [[THUNK_FUNC:%.*]] = function_ref @$sIeg_Ieg_TR :
9089
// CHECK: [[COPY_2_BORROWED_CLOSURE_1:%.*]] = copy_value [[COPY_BORROWED_CLOSURE_1]]
90+
// CHECK: [[THUNK_FUNC:%.*]] = function_ref @$sIeg_Ieg_TR :
9191
// CHECK: [[THUNK_PA:%.*]] = partial_apply [callee_guaranteed] [[THUNK_FUNC]]([[COPY_2_BORROWED_CLOSURE_1]])
9292
// CHECK: [[THUNK_PA_MDI:%.*]] = mark_dependence [[THUNK_PA]] : $@callee_guaranteed () -> () on [[COPY_BORROWED_CLOSURE_1]] : $@callee_guaranteed () -> ()
9393
// CHECK: destroy_value [[THUNK_PA_MDI]]

0 commit comments

Comments
 (0)