Skip to content

Commit c29eecd

Browse files
committed
[Property Wrappers] Store the callee in AppliedPropertyWrapperExpr to use
the correct substitution map when emitting the property wrapper generator application in SILGen.
1 parent bea89c6 commit c29eecd

File tree

5 files changed

+43
-13
lines changed

5 files changed

+43
-13
lines changed

include/swift/AST/Expr.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4237,6 +4237,9 @@ class AppliedPropertyWrapperExpr final : public Expr {
42374237
};
42384238

42394239
private:
4240+
/// The concrete callee which owns the property wrapper.
4241+
ConcreteDeclRef Callee;
4242+
42404243
/// The owning declaration.
42414244
const ParamDecl *Param;
42424245

@@ -4249,18 +4252,20 @@ class AppliedPropertyWrapperExpr final : public Expr {
42494252
/// The kind of value that the property wrapper is applied to.
42504253
ValueKind Kind;
42514254

4252-
AppliedPropertyWrapperExpr(const ParamDecl *param, SourceLoc loc,
4255+
AppliedPropertyWrapperExpr(ConcreteDeclRef callee, const ParamDecl *param, SourceLoc loc,
42534256
Type Ty, Expr *value, ValueKind kind)
42544257
: Expr(ExprKind::AppliedPropertyWrapper, /*Implicit=*/true, Ty),
4255-
Param(param), Loc(loc), Value(value), Kind(kind) {}
4258+
Callee(callee), Param(param), Loc(loc), Value(value), Kind(kind) {}
42564259

42574260
public:
42584261
static AppliedPropertyWrapperExpr *
4259-
create(ASTContext &ctx, const ParamDecl *param, SourceLoc loc,
4262+
create(ASTContext &ctx, ConcreteDeclRef callee, const ParamDecl *param, SourceLoc loc,
42604263
Type Ty, Expr *value, ValueKind kind);
42614264

42624265
SourceRange getSourceRange() const { return Loc; }
42634266

4267+
ConcreteDeclRef getCallee() { return Callee; }
4268+
42644269
/// Returns the parameter declaration with the attached property wrapper.
42654270
const ParamDecl *getParamDecl() const { return Param; };
42664271

lib/AST/Expr.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,10 +1510,11 @@ PropertyWrapperValuePlaceholderExpr::create(ASTContext &ctx, SourceRange range,
15101510
}
15111511

15121512
AppliedPropertyWrapperExpr *
1513-
AppliedPropertyWrapperExpr::create(ASTContext &ctx, const ParamDecl *param,
1513+
AppliedPropertyWrapperExpr::create(ASTContext &ctx, ConcreteDeclRef callee,
1514+
const ParamDecl *param,
15141515
SourceLoc loc, Type Ty, Expr *value,
15151516
AppliedPropertyWrapperExpr::ValueKind kind) {
1516-
return new (ctx) AppliedPropertyWrapperExpr(param, loc, Ty, value, kind);
1517+
return new (ctx) AppliedPropertyWrapperExpr(callee, param, loc, Ty, value, kind);
15171518
}
15181519

15191520
const ParamDecl *DefaultArgumentExpr::getParamDecl() const {

lib/SILGen/SILGenExpr.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5248,9 +5248,13 @@ RValue RValueEmitter::visitAppliedPropertyWrapperExpr(
52485248
break;
52495249
}
52505250

5251+
SubstitutionMap subs;
5252+
if (param->getDeclContext()->getAsDecl()) {
5253+
subs = E->getCallee().getSubstitutions();
5254+
}
5255+
52515256
return SGF.emitApplyOfPropertyWrapperBackingInitializer(
5252-
SILLocation(E), param, SGF.getForwardingSubstitutionMap(),
5253-
std::move(argument), initKind);
5257+
SILLocation(E), param, subs, std::move(argument), initKind);
52545258
}
52555259

52565260
ProtocolDecl *SILGenFunction::getPointerProtocol() {

lib/Sema/CSApply.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ namespace {
679679
declRefExpr->getFunctionRefKind() == FunctionRefKind::Unapplied)) {
680680
auto &appliedWrappers = solution.appliedPropertyWrappers[locator.getAnchor()];
681681
result = buildPropertyWrapperFnThunk(result, fullType->getAs<FunctionType>(), fnDecl,
682-
appliedWrappers);
682+
ref, appliedWrappers);
683683
}
684684
}
685685

@@ -978,7 +978,7 @@ namespace {
978978
}
979979

980980
AutoClosureExpr *buildPropertyWrapperFnThunk(
981-
Expr *fnRef, FunctionType *fnType, AnyFunctionRef fnDecl,
981+
Expr *fnRef, FunctionType *fnType, AnyFunctionRef fnDecl, ConcreteDeclRef ref,
982982
ArrayRef<AppliedPropertyWrapper> appliedPropertyWrappers) {
983983
auto &context = cs.getASTContext();
984984
auto paramInfo = fnType->getParams();
@@ -1018,7 +1018,7 @@ namespace {
10181018
ValueKind valueKind = (initKind == PropertyWrapperInitKind::ProjectedValue ?
10191019
ValueKind::ProjectedValue : ValueKind::WrappedValue);
10201020

1021-
paramRef = AppliedPropertyWrapperExpr::create(context, innerParam,
1021+
paramRef = AppliedPropertyWrapperExpr::create(context, ref, innerParam,
10221022
innerParam->getStartLoc(),
10231023
wrapperType, paramRef, valueKind);
10241024
cs.cacheExprTypes(paramRef);
@@ -1160,8 +1160,9 @@ namespace {
11601160
auto &appliedWrappers = solution.appliedPropertyWrappers[locator.getAnchor()];
11611161
if (!appliedWrappers.empty()) {
11621162
auto fnDecl = AnyFunctionRef(dyn_cast<AbstractFunctionDecl>(member));
1163+
auto callee = resolveConcreteDeclRef(member, locator);
11631164
auto *closure = buildPropertyWrapperFnThunk(selfCall, calleeFnType,
1164-
fnDecl, appliedWrappers);
1165+
fnDecl, callee, appliedWrappers);
11651166

11661167
ref->setType(FunctionType::get(refTy->getParams(), selfCall->getType()));
11671168
cs.cacheType(ref);
@@ -5841,7 +5842,7 @@ Expr *ExprRewriter::coerceCallArguments(
58415842
ValueKind valueKind = (initKind == PropertyWrapperInitKind::ProjectedValue ?
58425843
ValueKind::ProjectedValue : ValueKind::WrappedValue);
58435844

5844-
arg = AppliedPropertyWrapperExpr::create(ctx, param, arg->getStartLoc(),
5845+
arg = AppliedPropertyWrapperExpr::create(ctx, callee, param, arg->getStartLoc(),
58455846
wrapperType, arg, valueKind);
58465847
cs.cacheExprTypes(arg);
58475848
}
@@ -7852,7 +7853,7 @@ namespace {
78527853

78537854
auto &appliedWrappers = Rewriter.solution.appliedPropertyWrappers[closure];
78547855
return Rewriter.buildPropertyWrapperFnThunk(closure, closureFnType, closure,
7855-
appliedWrappers);
7856+
ConcreteDeclRef(), appliedWrappers);
78567857
}
78577858

78587859
/// Rewrite the function for the given solution.

test/SILGen/property_wrapper_parameter.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,25 @@ func simpleWrapperParameterCaller(projection: Projection<Int>) {
5151
// CHECK: function_ref @$s26property_wrapper_parameter26testSimpleWrapperParameter5valueyAA0F0VySiG_tFACL_SivpfW : $@convention(thin) (Projection<Int>) -> Wrapper<Int>
5252
}
5353

54+
// CHECK-LABEL: sil [ossa] @$s26property_wrapper_parameter18testGenericWrapper5valueyAA0F0VyxG_tlF : $@convention(thin) <T> (@in_guaranteed Wrapper<T>) -> ()
55+
public func testGenericWrapper<T>(@Wrapper value: T) {
56+
57+
// property wrapper backing initializer of value #1 in testGenericWrapper<A>(value:)
58+
// CHECK: sil non_abi [serialized] [ossa] @$s26property_wrapper_parameter18testGenericWrapper5valueyAA0F0VyxG_tlFACL_xvpfP : $@convention(thin) <T> (@in T) -> @out Wrapper<T>
59+
60+
// property wrapper init from projected value of value #1 in testGenericWrapper<A>(value:)
61+
// CHECK: sil non_abi [serialized] [ossa] @$s26property_wrapper_parameter18testGenericWrapper5valueyAA0F0VyxG_tlFACL_xvpfW : $@convention(thin) <T> (@in Projection<T>) -> @out Wrapper<T>
62+
}
63+
64+
// CHECK-LABEL: sil hidden [ossa] @$s26property_wrapper_parameter20genericWrapperCaller10projectionyAA10ProjectionVySiG_tF : $@convention(thin) (Projection<Int>) -> ()
65+
func genericWrapperCaller(projection: Projection<Int>) {
66+
testGenericWrapper(value: projection.wrappedValue)
67+
// CHECK: function_ref @$s26property_wrapper_parameter18testGenericWrapper5valueyAA0F0VyxG_tlFACL_xvpfP : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @out Wrapper<τ_0_0>
68+
69+
testGenericWrapper($value: projection)
70+
// CHECK: function_ref @$s26property_wrapper_parameter18testGenericWrapper5valueyAA0F0VyxG_tlFACL_xvpfW : $@convention(thin) <τ_0_0> (@in Projection<τ_0_0>) -> @out Wrapper<τ_0_0>
71+
}
72+
5473
// CHECK-LABEL: sil hidden [ossa] @$s26property_wrapper_parameter33testSimpleClosureWrapperParameteryyF : $@convention(thin) () -> ()
5574
func testSimpleClosureWrapperParameter() {
5675
let closure: (Int) -> Void = { (@Wrapper value: Int) in

0 commit comments

Comments
 (0)