Skip to content

Commit 13692fe

Browse files
committed
[Property Wrappers] Store property wrapper "init from projection" expressions
in PropertyWrapperBackingPropertyInfo.
1 parent aa0da03 commit 13692fe

File tree

11 files changed

+85
-49
lines changed

11 files changed

+85
-49
lines changed

include/swift/AST/PropertyWrappers.h

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ struct PropertyWrapperLValueness {
153153

154154
void simple_display(llvm::raw_ostream &os, PropertyWrapperLValueness l);
155155

156+
/// Given the initializer for a property with an attached property wrapper,
157+
/// dig out the wrapped value placeholder for the original initialization
158+
/// expression.
159+
///
160+
/// \note The wrapped value placeholder is injected for properties that can
161+
/// be initialized out-of-line using an expression of the wrapped property type.
162+
PropertyWrapperValuePlaceholderExpr *findWrappedValuePlaceholder(Expr *init);
163+
156164
/// Describes the backing property of a property that has an attached wrapper.
157165
struct PropertyWrapperBackingPropertyInfo {
158166
/// The backing property.
@@ -162,30 +170,67 @@ struct PropertyWrapperBackingPropertyInfo {
162170
/// of the original wrapped property prefixed with \c $
163171
VarDecl *projectionVar = nullptr;
164172

165-
/// An expression that initializes the backing property from a value of
166-
/// the original property's type (e.g., via `init(wrappedValue:)`), or
167-
/// \c NULL if the backing property can only be initialized directly.
168-
Expr *initializeFromOriginal = nullptr;
173+
private:
174+
struct {
175+
/// An expression that initializes the backing property from a value of
176+
/// the original property's type via \c init(wrappedValue:) if supported
177+
/// by the wrapper type.
178+
Expr *expr = nullptr;
179+
180+
/// When \c expr is not null, the opaque value that is used as
181+
/// a placeholder for a value of the original property's type.
182+
PropertyWrapperValuePlaceholderExpr *placeholder = nullptr;
183+
} wrappedValueInit;
184+
185+
struct {
186+
/// An expression that initializes the backing property from a value of
187+
/// the synthesized projection type via \c init(projectedValue:) if
188+
/// supported by the wrapper type.
189+
Expr *expr = nullptr;
190+
191+
/// When \c expr is not null, the opaque value that is used as
192+
/// a placeholder for a value of the projection type.
193+
PropertyWrapperValuePlaceholderExpr *placeholder = nullptr;
194+
} projectedValueInit;
195+
196+
public:
197+
PropertyWrapperBackingPropertyInfo() { }
169198

170-
/// When \c initializeFromOriginal is non-NULL, the opaque value that
171-
/// is used as a stand-in for a value of the original property's type.
172-
PropertyWrapperValuePlaceholderExpr *wrappedValuePlaceholder = nullptr;
199+
PropertyWrapperBackingPropertyInfo(VarDecl *backingVar, VarDecl *projectionVar)
200+
: backingVar(backingVar), projectionVar(projectionVar) { }
173201

174-
PropertyWrapperBackingPropertyInfo() { }
175-
176-
PropertyWrapperBackingPropertyInfo(VarDecl *backingVar,
177-
VarDecl *projectionVar,
178-
Expr *initializeFromOriginal,
179-
PropertyWrapperValuePlaceholderExpr *placeholder)
180-
: backingVar(backingVar), projectionVar(projectionVar),
181-
initializeFromOriginal(initializeFromOriginal),
182-
wrappedValuePlaceholder(placeholder) { }
202+
PropertyWrapperBackingPropertyInfo(VarDecl *backingVar, VarDecl *projectionVar,
203+
Expr *wrappedValueInitExpr,
204+
Expr *projectedValueInitExpr)
205+
: backingVar(backingVar), projectionVar(projectionVar) {
206+
wrappedValueInit.expr = wrappedValueInitExpr;
207+
if (wrappedValueInitExpr) {
208+
wrappedValueInit.placeholder = findWrappedValuePlaceholder(wrappedValueInitExpr);
209+
}
210+
211+
projectedValueInit.expr = projectedValueInitExpr;
212+
if (projectedValueInitExpr) {
213+
projectedValueInit.placeholder = findWrappedValuePlaceholder(projectedValueInitExpr);
214+
}
215+
}
183216

184217
/// Whether this is a valid property wrapper.
185218
bool isValid() const {
186219
return backingVar != nullptr;
187220
}
188221

222+
bool hasInitFromWrappedValue() const {
223+
return wrappedValueInit.expr != nullptr;
224+
}
225+
226+
Expr *getInitFromWrappedValue() {
227+
return wrappedValueInit.expr;
228+
}
229+
230+
PropertyWrapperValuePlaceholderExpr *getWrappedValuePlaceholder() {
231+
return wrappedValueInit.placeholder;
232+
}
233+
189234
explicit operator bool() const { return isValid(); }
190235

191236
friend bool operator==(const PropertyWrapperBackingPropertyInfo &lhs,
@@ -203,14 +248,6 @@ void simple_display(
203248
llvm::raw_ostream &out,
204249
const PropertyWrapperBackingPropertyInfo &backingInfo);
205250

206-
/// Given the initializer for a property with an attached property wrapper,
207-
/// dig out the wrapped value placeholder for the original initialization
208-
/// expression.
209-
///
210-
/// \note The wrapped value placeholder is injected for properties that can
211-
/// be initialized out-of-line using an expression of the wrapped property type.
212-
PropertyWrapperValuePlaceholderExpr *findWrappedValuePlaceholder(Expr *init);
213-
214251
} // end namespace swift
215252

216253
#endif // SWIFT_AST_PROPERTY_WRAPPERS_H

lib/AST/Decl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6034,10 +6034,10 @@ bool VarDecl::isPropertyMemberwiseInitializedWithWrappedType() const {
60346034

60356035
Type VarDecl::getPropertyWrapperInitValueInterfaceType() const {
60366036
auto wrapperInfo = getPropertyWrapperBackingPropertyInfo();
6037-
if (!wrapperInfo || !wrapperInfo.wrappedValuePlaceholder)
6037+
if (!wrapperInfo || !wrapperInfo.getWrappedValuePlaceholder())
60386038
return Type();
60396039

6040-
Type valueInterfaceTy = wrapperInfo.wrappedValuePlaceholder->getType();
6040+
Type valueInterfaceTy = wrapperInfo.getWrappedValuePlaceholder()->getType();
60416041
if (valueInterfaceTy->hasArchetype())
60426042
valueInterfaceTy = valueInterfaceTy->mapTypeOutOfContext();
60436043

lib/SILGen/SILGen.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -900,8 +900,8 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) {
900900
->isPropertyMemberwiseInitializedWithWrappedType()) {
901901
auto wrapperInfo =
902902
originalProperty->getPropertyWrapperBackingPropertyInfo();
903-
assert(wrapperInfo.wrappedValuePlaceholder->getOriginalWrappedValue());
904-
init = wrapperInfo.wrappedValuePlaceholder->getOriginalWrappedValue();
903+
assert(wrapperInfo.getWrappedValuePlaceholder()->getOriginalWrappedValue());
904+
init = wrapperInfo.getWrappedValuePlaceholder()->getOriginalWrappedValue();
905905
}
906906
}
907907

@@ -934,12 +934,12 @@ void SILGenModule::emitFunctionDefinition(SILDeclRef constant, SILFunction *f) {
934934
PrettyStackTraceSILFunction X(
935935
"silgen emitPropertyWrapperBackingInitializer", f);
936936
auto wrapperInfo = var->getPropertyWrapperBackingPropertyInfo();
937-
assert(wrapperInfo.initializeFromOriginal);
938-
f->createProfiler(wrapperInfo.initializeFromOriginal, constant,
937+
assert(wrapperInfo.hasInitFromWrappedValue());
938+
f->createProfiler(wrapperInfo.getInitFromWrappedValue(), constant,
939939
ForDefinition);
940940
auto varDC = var->getInnermostDeclContext();
941941
SILGenFunction SGF(*this, *f, varDC);
942-
SGF.emitGeneratorFunction(constant, wrapperInfo.initializeFromOriginal);
942+
SGF.emitGeneratorFunction(constant, wrapperInfo.getInitFromWrappedValue());
943943
postEmitFunction(constant, f);
944944
break;
945945
}

lib/SILGen/SILGenConstructor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ static RValue maybeEmitPropertyWrapperInitFromValue(
117117
return std::move(arg);
118118

119119
auto wrapperInfo = originalProperty->getPropertyWrapperBackingPropertyInfo();
120-
if (!wrapperInfo || !wrapperInfo.initializeFromOriginal)
120+
if (!wrapperInfo || !wrapperInfo.hasInitFromWrappedValue())
121121
return std::move(arg);
122122

123123
return SGF.emitApplyOfPropertyWrapperBackingInitializer(loc, originalProperty,
@@ -246,7 +246,7 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
246246
// the property wrapper backing initializer.
247247
if (auto *wrappedVar = field->getOriginalWrappedProperty()) {
248248
auto wrappedInfo = wrappedVar->getPropertyWrapperBackingPropertyInfo();
249-
auto *placeholder = wrappedInfo.wrappedValuePlaceholder;
249+
auto *placeholder = wrappedInfo.getWrappedValuePlaceholder();
250250
if (placeholder && placeholder->getOriginalWrappedValue()) {
251251
auto arg = SGF.emitRValue(placeholder->getOriginalWrappedValue());
252252
maybeEmitPropertyWrapperInitFromValue(SGF, Loc, field, subs,
@@ -291,7 +291,7 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
291291
// memberwise initialized, use the original wrapped value if it exists.
292292
if (auto *wrappedVar = field->getOriginalWrappedProperty()) {
293293
auto wrappedInfo = wrappedVar->getPropertyWrapperBackingPropertyInfo();
294-
auto *placeholder = wrappedInfo.wrappedValuePlaceholder;
294+
auto *placeholder = wrappedInfo.getWrappedValuePlaceholder();
295295
if (placeholder && placeholder->getOriginalWrappedValue()) {
296296
init = placeholder->getOriginalWrappedValue();
297297
}

lib/SILGen/SILGenDecl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1190,7 +1190,7 @@ void SILGenFunction::emitPatternBinding(PatternBindingDecl *PBD,
11901190
if (var && var->getDeclContext()->isLocalContext()) {
11911191
if (auto *orig = var->getOriginalWrappedProperty()) {
11921192
auto wrapperInfo = orig->getPropertyWrapperBackingPropertyInfo();
1193-
Init = wrapperInfo.wrappedValuePlaceholder->getOriginalWrappedValue();
1193+
Init = wrapperInfo.getWrappedValuePlaceholder()->getOriginalWrappedValue();
11941194

11951195
auto value = emitRValue(Init);
11961196
emitApplyOfPropertyWrapperBackingInitializer(SILLocation(PBD), orig,
@@ -1225,7 +1225,7 @@ void SILGenFunction::visitVarDecl(VarDecl *D) {
12251225
if (D->getAttrs().hasAttribute<CustomAttr>()) {
12261226
// Emit the property wrapper backing initializer if necessary.
12271227
auto wrapperInfo = D->getPropertyWrapperBackingPropertyInfo();
1228-
if (wrapperInfo && wrapperInfo.initializeFromOriginal)
1228+
if (wrapperInfo && wrapperInfo.hasInitFromWrappedValue())
12291229
SGM.emitPropertyWrapperBackingInitializer(D);
12301230
}
12311231

lib/SILGen/SILGenFunction.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -929,12 +929,12 @@ void SILGenFunction::emitGeneratorFunction(SILDeclRef function, Expr *value,
929929
auto var = cast<VarDecl>(function.getDecl());
930930
auto wrappedInfo = var->getPropertyWrapperBackingPropertyInfo();
931931
auto param = params->get(0);
932-
auto *placeholder = wrappedInfo.wrappedValuePlaceholder;
932+
auto *placeholder = wrappedInfo.getWrappedValuePlaceholder();
933933
opaqueValue.emplace(
934934
*this, placeholder->getOpaqueValuePlaceholder(),
935935
maybeEmitValueOfLocalVarDecl(param, AccessKind::Read));
936936

937-
assert(value == wrappedInfo.initializeFromOriginal);
937+
assert(value == wrappedInfo.getInitFromWrappedValue());
938938
}
939939

940940
emitReturnExpr(Loc, value);

lib/SILGen/SILGenLValue.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,7 +1307,7 @@ namespace {
13071307
// If this is not a wrapper property that can be initialized from
13081308
// a value of the wrapped type, we can't perform the initialization.
13091309
auto wrapperInfo = VD->getPropertyWrapperBackingPropertyInfo();
1310-
if (!wrapperInfo.initializeFromOriginal)
1310+
if (!wrapperInfo.hasInitFromWrappedValue())
13111311
return false;
13121312

13131313
bool isAssignmentToSelfParamInInit =
@@ -1322,14 +1322,14 @@ namespace {
13221322
// If this var isn't in a type context, assignment will always use the setter
13231323
// if there is an initial value.
13241324
if (!VD->getDeclContext()->isTypeContext() &&
1325-
wrapperInfo.wrappedValuePlaceholder->getOriginalWrappedValue())
1325+
wrapperInfo.getWrappedValuePlaceholder()->getOriginalWrappedValue())
13261326
return false;
13271327

13281328
// If this property wrapper uses autoclosure in it's initializer,
13291329
// the argument types of the setter and initializer shall be
13301330
// different, so we don't rewrite an assignment into an
13311331
// initialization.
1332-
return !wrapperInfo.wrappedValuePlaceholder->isAutoClosure();
1332+
return !wrapperInfo.getWrappedValuePlaceholder()->isAutoClosure();
13331333
}
13341334

13351335
return false;

lib/SILGen/SILGenType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1135,7 +1135,7 @@ class SILGenType : public TypeMemberVisitor<SILGenType> {
11351135
// If this variable has an attached property wrapper with an initialization
11361136
// function, emit the backing initializer function.
11371137
if (auto wrapperInfo = vd->getPropertyWrapperBackingPropertyInfo()) {
1138-
if (wrapperInfo.initializeFromOriginal && !vd->isStatic()) {
1138+
if (wrapperInfo.hasInitFromWrappedValue() && !vd->isStatic()) {
11391139
SGM.emitPropertyWrapperBackingInitializer(vd);
11401140
}
11411141
}

lib/Sema/CodeSynthesis.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ static ConstructorDecl *createImplicitConstructor(NominalTypeDecl *decl,
266266
varInterfaceType = var->getPropertyWrapperInitValueInterfaceType();
267267

268268
auto wrapperInfo = var->getPropertyWrapperBackingPropertyInfo();
269-
isAutoClosure = wrapperInfo.wrappedValuePlaceholder->isAutoClosure();
269+
isAutoClosure = wrapperInfo.getWrappedValuePlaceholder()->isAutoClosure();
270270
} else {
271271
varInterfaceType = backingPropertyType;
272272
}

lib/Sema/TypeCheckStorage.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2736,7 +2736,7 @@ PropertyWrapperBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
27362736
wrapperInfo.projectedValueVar);
27372737
}
27382738

2739-
return PropertyWrapperBackingPropertyInfo(backingVar, projectionVar, nullptr, nullptr);
2739+
return PropertyWrapperBackingPropertyInfo(backingVar, projectionVar);
27402740
}
27412741

27422742
if (!wrapperInfo)
@@ -2834,8 +2834,7 @@ PropertyWrapperBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
28342834
// value.
28352835
if (!wrappedValue && (!var->allAttachedPropertyWrappersHaveWrappedValueInit() ||
28362836
initializer)) {
2837-
return PropertyWrapperBackingPropertyInfo(
2838-
backingVar, storageVar, nullptr, nullptr);
2837+
return PropertyWrapperBackingPropertyInfo(backingVar, storageVar);
28392838
}
28402839

28412840
// Form the initialization of the backing property from a value of the
@@ -2845,11 +2844,11 @@ PropertyWrapperBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
28452844
ctx, var->getSourceRange(), var->getType(), /*wrappedValue=*/nullptr);
28462845
typeCheckSynthesizedWrapperInitializer(
28472846
pbd, backingVar, parentPBD, initializer);
2848-
wrappedValue = findWrappedValuePlaceholder(initializer);
28492847
}
28502848

28512849
return PropertyWrapperBackingPropertyInfo(backingVar, storageVar,
2852-
initializer, wrappedValue);
2850+
/*wrappedValueInitExpr=*/initializer,
2851+
/*projectedValueInitExpr=*/nullptr);
28532852
}
28542853

28552854
VarDecl *

0 commit comments

Comments
 (0)