Skip to content

Commit b2562da

Browse files
authored
Merge pull request #5590 from jckarter/lowerable-type-to-id
SILGen: Skip the value-to-id peephole for types with nontrivial SIL lowering.
2 parents 70cf363 + cf5134a commit b2562da

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

lib/SILGen/SILGenApply.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3171,6 +3171,7 @@ namespace {
31713171
SILParameterInfo param) {
31723172
// If we're bridging a concrete type to `id` via Any, skip the Any
31733173
// boxing.
3174+
31743175
// TODO: Generalize. Similarly, when bridging from NSFoo -> Foo -> NSFoo,
31753176
// we should elide the bridge altogether and pass the original object.
31763177
auto paramObjTy = param.getType();
@@ -3186,9 +3187,8 @@ namespace {
31863187
origParamType, param);
31873188

31883189
return SGF.emitNativeToBridgedValue(emitted.loc,
3189-
std::move(emitted.value).getScalarValue(),
3190-
Rep, param.getType());
3191-
3190+
std::move(emitted.value).getAsSingleValue(SGF, emitted.loc),
3191+
Rep, param.getType());
31923192
}
31933193

31943194
enum class ExistentialPeepholeOptionality {
@@ -3277,15 +3277,24 @@ namespace {
32773277
AbstractionPattern origParamType,
32783278
SILParameterInfo param) {
32793279
auto origArgExpr = argExpr;
3280-
(void) origArgExpr;
32813280
// Look through existential erasures.
32823281
ExistentialPeepholeOptionality optionality;
32833282
std::tie(argExpr, optionality) = lookThroughExistentialErasures(argExpr);
32843283

3284+
// TODO: Only do the peephole for trivially-lowered types, since we
3285+
// unfortunately don't plumb formal types through
3286+
// emitNativeToBridgedValue, so can't correctly construct the
3287+
// substitution for the call to _bridgeAnythingToObjectiveC for function
3288+
// or metatype values.
3289+
if (!argExpr->getType()->isLegalSILType()) {
3290+
argExpr = origArgExpr;
3291+
optionality = ExistentialPeepholeOptionality::Nonoptional;
3292+
}
3293+
32853294
// Emit the argument.
32863295
auto contexts = getRValueEmissionContexts(loweredSubstArgType, param);
32873296
ManagedValue emittedArg = SGF.emitRValue(argExpr, contexts.ForEmission)
3288-
.getScalarValue();
3297+
.getAsSingleValue(SGF, argExpr);
32893298

32903299
// Early exit if we already exactly match the parameter type.
32913300
if (emittedArg.getType() == param.getSILType()) {

test/SILGen/objc_bridging_any.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,24 @@ func passingToId<T: CP, U>(receiver: NSIdLover,
153153
receiver.takesId(optionalC)
154154

155155
// TODO: Property and subscript setters
156+
157+
}
158+
159+
// Workaround for rdar://problem/28318984. Skip the peephole for types with
160+
// nontrivial SIL lowerings because we don't correctly form the substitutions
161+
// for a generic _bridgeAnythingToObjectiveC call.
162+
func zim() {}
163+
struct Zang {}
164+
// CHECK-LABEL: sil hidden @_TF17objc_bridging_any27typesWithNontrivialLoweringFT8receiverCSo9NSIdLover_T_
165+
func typesWithNontrivialLowering(receiver: NSIdLover) {
166+
// CHECK: init_existential_addr {{%.*}} : $*Any, $() -> ()
167+
receiver.takesId(zim)
168+
// CHECK: init_existential_addr {{%.*}} : $*Any, $Zang.Type
169+
receiver.takesId(Zang.self)
170+
// CHECK: init_existential_addr {{%.*}} : $*Any, $(() -> (), Zang.Type)
171+
receiver.takesId((zim, Zang.self))
172+
// CHECK: apply {{%.*}}<(Int, String)>
173+
receiver.takesId((0, "one"))
156174
}
157175

158176
// CHECK-LABEL: sil hidden @_TF17objc_bridging_any19passingToNullableId

0 commit comments

Comments
 (0)