Skip to content

Commit a6c33a9

Browse files
committed
[Property Wrappers] Use autoclosure information from CSApply to compute
`VarDecl::getPropertyWrapperInitValueInterfaceType`.
1 parent bf47403 commit a6c33a9

18 files changed

+137
-159
lines changed

include/swift/AST/Decl.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5221,10 +5221,6 @@ class VarDecl : public AbstractStorageDecl {
52215221
/// a suitable `init(wrappedValue:)`.
52225222
bool isPropertyMemberwiseInitializedWithWrappedType() const;
52235223

5224-
/// Whether the innermost property wrapper's initializer's 'wrappedValue' parameter
5225-
/// is marked with '@autoclosure' and '@escaping'.
5226-
bool isInnermostPropertyWrapperInitUsesEscapingAutoClosure() const;
5227-
52285224
/// Return the interface type of the value used for the 'wrappedValue:'
52295225
/// parameter when initializing a property wrapper.
52305226
///

include/swift/AST/Expr.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4165,16 +4165,20 @@ class PropertyWrapperValuePlaceholderExpr : public Expr {
41654165
SourceRange Range;
41664166
OpaqueValueExpr *Placeholder;
41674167
Expr *WrappedValue;
4168+
bool IsAutoClosure = false;
41684169

41694170
PropertyWrapperValuePlaceholderExpr(SourceRange Range, Type Ty,
41704171
OpaqueValueExpr *placeholder,
4171-
Expr *wrappedValue)
4172+
Expr *wrappedValue,
4173+
bool isAutoClosure)
41724174
: Expr(ExprKind::PropertyWrapperValuePlaceholder, /*Implicit=*/true, Ty),
4173-
Range(Range), Placeholder(placeholder), WrappedValue(wrappedValue) {}
4175+
Range(Range), Placeholder(placeholder), WrappedValue(wrappedValue),
4176+
IsAutoClosure(isAutoClosure) {}
41744177

41754178
public:
41764179
static PropertyWrapperValuePlaceholderExpr *
4177-
create(ASTContext &ctx, SourceRange range, Type ty, Expr *wrappedValue);
4180+
create(ASTContext &ctx, SourceRange range, Type ty, Expr *wrappedValue,
4181+
bool isAutoClosure = false);
41784182

41794183
/// The original wrappedValue initialization expression provided via
41804184
/// \c = on a proprety with attached property wrappers.
@@ -4196,6 +4200,8 @@ class PropertyWrapperValuePlaceholderExpr : public Expr {
41964200
Placeholder = placeholder;
41974201
}
41984202

4203+
bool isAutoClosure() const { return IsAutoClosure; }
4204+
41994205
SourceRange getSourceRange() const { return Range; }
42004206

42014207
static bool classof(const Expr *E) {

include/swift/AST/PropertyWrappers.h

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ struct PropertyWrapperTypeInfo {
4343
HasInitialValueInit
4444
} wrappedValueInit = NoWrappedValueInit;
4545

46-
/// Whether the init(wrappedValue:), if it exists, has the wrappedValue
47-
/// argument as an escaping autoclosure.
48-
bool isWrappedValueInitUsingEscapingAutoClosure = false;
49-
5046
/// The initializer that will be called to default-initialize a
5147
/// value with an attached property wrapper.
5248
enum {
@@ -153,37 +149,24 @@ struct PropertyWrapperBackingPropertyInfo {
153149
/// '$foo' from `backingVar`.
154150
VarDecl *storageWrapperVar = nullptr;
155151

156-
/// When the original default value is specified in terms of an '='
157-
/// initializer on the initial property, e.g.,
158-
///
159-
/// \code
160-
/// @Lazy var i = 17
161-
/// \endcode
162-
///
163-
/// This is the specified initial value (\c 17), which is suitable for
164-
/// embedding in the expression \c initializeFromOriginal.
165-
Expr *originalInitialValue = nullptr;
166-
167152
/// An expression that initializes the backing property from a value of
168153
/// the original property's type (e.g., via `init(wrappedValue:)`), or
169154
/// \c NULL if the backing property can only be initialized directly.
170155
Expr *initializeFromOriginal = nullptr;
171156

172157
/// When \c initializeFromOriginal is non-NULL, the opaque value that
173158
/// is used as a stand-in for a value of the original property's type.
174-
OpaqueValueExpr *underlyingValue = nullptr;
159+
PropertyWrapperValuePlaceholderExpr *wrappedValuePlaceholder = nullptr;
175160

176161
PropertyWrapperBackingPropertyInfo() { }
177162

178163
PropertyWrapperBackingPropertyInfo(VarDecl *backingVar,
179-
VarDecl *storageWrapperVar,
180-
Expr *originalInitialValue,
181-
Expr *initializeFromOriginal,
182-
OpaqueValueExpr *underlyingValue)
164+
VarDecl *storageWrapperVar,
165+
Expr *initializeFromOriginal,
166+
PropertyWrapperValuePlaceholderExpr *placeholder)
183167
: backingVar(backingVar), storageWrapperVar(storageWrapperVar),
184-
originalInitialValue(originalInitialValue),
185168
initializeFromOriginal(initializeFromOriginal),
186-
underlyingValue(underlyingValue) { }
169+
wrappedValuePlaceholder(placeholder) { }
187170

188171
/// Whether this is a valid property wrapper.
189172
bool isValid() const {

lib/AST/Decl.cpp

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6067,21 +6067,14 @@ bool VarDecl::isPropertyMemberwiseInitializedWithWrappedType() const {
60676067
return allAttachedPropertyWrappersHaveWrappedValueInit();
60686068
}
60696069

6070-
bool VarDecl::isInnermostPropertyWrapperInitUsesEscapingAutoClosure() const {
6071-
auto customAttrs = getAttachedPropertyWrappers();
6072-
if (customAttrs.empty())
6073-
return false;
6074-
6075-
unsigned innermostWrapperIndex = customAttrs.size() - 1;
6076-
auto typeInfo = getAttachedPropertyWrapperTypeInfo(innermostWrapperIndex);
6077-
return typeInfo.isWrappedValueInitUsingEscapingAutoClosure;
6078-
}
6079-
60806070
Type VarDecl::getPropertyWrapperInitValueInterfaceType() const {
6081-
Type valueInterfaceTy = getValueInterfaceType();
6071+
auto wrapperInfo = getPropertyWrapperBackingPropertyInfo();
6072+
if (!wrapperInfo || !wrapperInfo.wrappedValuePlaceholder)
6073+
return Type();
60826074

6083-
if (isInnermostPropertyWrapperInitUsesEscapingAutoClosure())
6084-
return FunctionType::get({}, valueInterfaceTy);
6075+
Type valueInterfaceTy = wrapperInfo.wrappedValuePlaceholder->getType();
6076+
if (valueInterfaceTy->hasArchetype())
6077+
valueInterfaceTy = valueInterfaceTy->mapTypeOutOfContext();
60856078

60866079
return valueInterfaceTy;
60876080
}

lib/AST/Expr.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,13 +1463,13 @@ static ValueDecl *getCalledValue(Expr *E) {
14631463

14641464
PropertyWrapperValuePlaceholderExpr *
14651465
PropertyWrapperValuePlaceholderExpr::create(ASTContext &ctx, SourceRange range,
1466-
Type ty, Expr *wrappedValue) {
1466+
Type ty, Expr *wrappedValue,
1467+
bool isAutoClosure) {
14671468
auto *placeholder =
14681469
new (ctx) OpaqueValueExpr(range, ty, /*isPlaceholder=*/true);
14691470

1470-
return new (ctx) PropertyWrapperValuePlaceholderExpr(range, ty,
1471-
placeholder,
1472-
wrappedValue);
1471+
return new (ctx) PropertyWrapperValuePlaceholderExpr(
1472+
range, ty, placeholder, wrappedValue, isAutoClosure);
14731473
}
14741474

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

lib/SILGen/SILGen.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -772,8 +772,8 @@ static void emitDelayedFunction(SILGenModule &SGM,
772772
->isPropertyMemberwiseInitializedWithWrappedType()) {
773773
auto wrapperInfo =
774774
originalProperty->getPropertyWrapperBackingPropertyInfo();
775-
assert(wrapperInfo.originalInitialValue);
776-
init = wrapperInfo.originalInitialValue;
775+
assert(wrapperInfo.wrappedValuePlaceholder->getOriginalWrappedValue());
776+
init = wrapperInfo.wrappedValuePlaceholder->getOriginalWrappedValue();
777777
}
778778
}
779779

lib/SILGen/SILGenConstructor.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,9 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
230230
// the property wrapper backing initializer.
231231
if (auto *wrappedVar = field->getOriginalWrappedProperty()) {
232232
auto wrappedInfo = wrappedVar->getPropertyWrapperBackingPropertyInfo();
233-
if (wrappedInfo.originalInitialValue) {
234-
auto arg = SGF.emitRValue(wrappedInfo.originalInitialValue);
233+
auto *placeholder = wrappedInfo.wrappedValuePlaceholder;
234+
if (placeholder && placeholder->getOriginalWrappedValue()) {
235+
auto arg = SGF.emitRValue(placeholder->getOriginalWrappedValue());
235236
maybeEmitPropertyWrapperInitFromValue(SGF, Loc, field, subs,
236237
std::move(arg))
237238
.forwardInto(SGF, Loc, init.get());
@@ -274,8 +275,9 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
274275
// memberwise initialized, use the original wrapped value if it exists.
275276
if (auto *wrappedVar = field->getOriginalWrappedProperty()) {
276277
auto wrappedInfo = wrappedVar->getPropertyWrapperBackingPropertyInfo();
277-
if (wrappedInfo.originalInitialValue) {
278-
init = wrappedInfo.originalInitialValue;
278+
auto *placeholder = wrappedInfo.wrappedValuePlaceholder;
279+
if (placeholder && placeholder->getOriginalWrappedValue()) {
280+
init = placeholder->getOriginalWrappedValue();
279281
}
280282
}
281283

lib/SILGen/SILGenFunction.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,7 +852,8 @@ void SILGenFunction::emitGeneratorFunction(SILDeclRef function, Expr *value,
852852
auto var = cast<VarDecl>(function.getDecl());
853853
auto wrappedInfo = var->getPropertyWrapperBackingPropertyInfo();
854854
auto param = params->get(0);
855-
opaqueValue.emplace(*this, wrappedInfo.underlyingValue,
855+
auto *placeholder = wrappedInfo.wrappedValuePlaceholder;
856+
opaqueValue.emplace(*this, placeholder->getOpaqueValuePlaceholder(),
856857
maybeEmitValueOfLocalVarDecl(param));
857858

858859
assert(value == wrappedInfo.initializeFromOriginal);

lib/SILGen/SILGenLValue.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1335,10 +1335,7 @@ namespace {
13351335
// the argument types of the setter and initializer shall be
13361336
// different, so we don't rewrite an assignment into an
13371337
// initialization.
1338-
if (VD->isInnermostPropertyWrapperInitUsesEscapingAutoClosure())
1339-
return false;
1340-
1341-
return true;
1338+
return !wrapperInfo.wrappedValuePlaceholder->isAutoClosure();
13421339
}
13431340

13441341
return false;

lib/Sema/CSApply.cpp

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5489,8 +5489,10 @@ Expr *ExprRewriter::coerceCallArguments(Expr *arg, AnyFunctionType *funcType,
54895489
target->shouldInjectWrappedValuePlaceholder(apply);
54905490

54915491
auto injectWrappedValuePlaceholder = [&](Expr *arg) -> Expr * {
5492-
auto *placeholder = PropertyWrapperValuePlaceholderExpr::create(ctx,
5493-
arg->getSourceRange(), cs.getType(arg), arg);
5492+
auto *placeholder = PropertyWrapperValuePlaceholderExpr::create(
5493+
ctx, arg->getSourceRange(), cs.getType(arg),
5494+
target->propertyWrapperHasInitialWrappedValue() ? arg : nullptr,
5495+
isa<AutoClosureExpr>(arg));
54945496
cs.cacheType(placeholder);
54955497
cs.cacheType(placeholder->getOpaqueValuePlaceholder());
54965498
shouldInjectWrappedValuePlaceholder = false;
@@ -5690,19 +5692,15 @@ Expr *ExprRewriter::coerceCallArguments(Expr *arg, AnyFunctionType *funcType,
56905692
locator.withPathElement(ConstraintLocator::AutoclosureResult));
56915693

56925694
if (shouldInjectWrappedValuePlaceholder) {
5693-
// If init(wrappedValue:) takes an escaping autoclosure, then we want
5695+
// If init(wrappedValue:) takes an autoclosure, then we want
56945696
// the effect of autoclosure forwarding of the placeholder
56955697
// autoclosure. The only way to do this is to call the placeholder
56965698
// autoclosure when passing it to the init.
5697-
if (!closureType->isNoEscape()) {
5698-
auto *placeholder = injectWrappedValuePlaceholder(
5699-
cs.buildAutoClosureExpr(arg, closureType));
5700-
arg = CallExpr::createImplicit(ctx, placeholder, {}, {});
5701-
arg->setType(closureType->getResult());
5702-
cs.cacheType(arg);
5703-
} else {
5704-
arg = injectWrappedValuePlaceholder(arg);
5705-
}
5699+
auto *placeholder = injectWrappedValuePlaceholder(
5700+
cs.buildAutoClosureExpr(arg, closureType));
5701+
arg = CallExpr::createImplicit(ctx, placeholder, {}, {});
5702+
arg->setType(closureType->getResult());
5703+
cs.cacheType(arg);
57065704
}
57075705

57085706
convertedArg = cs.buildAutoClosureExpr(arg, closureType);

0 commit comments

Comments
 (0)