Skip to content

Commit 88d91f3

Browse files
committed
---
yaml --- r: 348111 b: refs/heads/master c: 51a9878 h: refs/heads/master i: 348109: 4a283a8 348107: ffd55b3 348103: c9988da 348095: 19c30ef
1 parent f4c001e commit 88d91f3

File tree

11 files changed

+296
-149
lines changed

11 files changed

+296
-149
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 823608041cd74cf53fa8fcf8cdfd77a3678ba4b6
2+
refs/heads/master: 51a987870beda8b648c68e295f49d99f4d062c6b
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4387,7 +4387,8 @@ ERROR(property_wrapper_ambiguous_value_property, none,
43874387
"named %1", (Type, Identifier))
43884388
ERROR(property_wrapper_wrong_initial_value_init, none,
43894389
"'init(initialValue:)' parameter type (%0) must be the same as its "
4390-
"'value' property type (%1) or an @autoclosure thereof", (Type, Type))
4390+
"'wrappedValue' property type (%1) or an @autoclosure thereof",
4391+
(Type, Type))
43914392
ERROR(property_wrapper_failable_init, none,
43924393
"%0 cannot be failable", (DeclName))
43934394
ERROR(property_wrapper_ambiguous_initial_value_init, none,
@@ -4440,7 +4441,7 @@ NOTE(property_wrapper_direct_init,none,
44404441
"'(...') on the attribute", ())
44414442

44424443
ERROR(property_wrapper_incompatible_property, none,
4443-
"property type %0 does not match that of the 'value' property of "
4444+
"property type %0 does not match that of the 'wrappedValue' property of "
44444445
"its wrapper type %1", (Type, Type))
44454446

44464447
ERROR(property_wrapper_type_access,none,
@@ -4460,6 +4461,9 @@ ERROR(property_wrapper_type_not_usable_from_inline,none,
44604461
WARNING(property_wrapper_delegateValue,none,
44614462
"property wrapper's `delegateValue` property should be renamed to "
44624463
"'wrapperValue'; use of 'delegateValue' is deprecated", ())
4464+
WARNING(property_wrapper_value,none,
4465+
"property wrapper's `value` property should be renamed to "
4466+
"'wrappedValue'; use of 'value' is deprecated", ())
44634467

44644468
//------------------------------------------------------------------------------
44654469
// MARK: function builder diagnostics

trunk/include/swift/AST/KnownIdentifiers.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ IDENTIFIER(WinSDK)
121121
IDENTIFIER(with)
122122
IDENTIFIER(withArguments)
123123
IDENTIFIER(withKeywordArguments)
124+
IDENTIFIER(wrappedValue)
124125
IDENTIFIER(wrapperValue)
125126

126127
// Kinds of layout constraints

trunk/lib/AST/Decl.cpp

Lines changed: 73 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5489,12 +5489,13 @@ VarDecl *VarDecl::getPropertyWrapperBackingProperty() const {
54895489
return getPropertyWrapperBackingPropertyInfo().backingVar;
54905490
}
54915491

5492-
bool VarDecl::isPropertyWrapperInitializedWithInitialValue() const {
5493-
auto customAttrs = getAttachedPropertyWrappers();
5492+
static bool propertyWrapperInitializedViaInitialValue(
5493+
const VarDecl *var, bool checkDefaultInit) {
5494+
auto customAttrs = var->getAttachedPropertyWrappers();
54945495
if (customAttrs.empty())
54955496
return false;
54965497

5497-
auto *PBD = getParentPatternBinding();
5498+
auto *PBD = var->getParentPatternBinding();
54985499
if (!PBD)
54995500
return false;
55005501

@@ -5509,36 +5510,23 @@ bool VarDecl::isPropertyWrapperInitializedWithInitialValue() const {
55095510
return false;
55105511

55115512
// Default initialization does not use a value.
5512-
if (getAttachedPropertyWrapperTypeInfo(0).defaultInit)
5513+
if (checkDefaultInit &&
5514+
var->getAttachedPropertyWrapperTypeInfo(0).defaultInit)
55135515
return false;
55145516

55155517
// If all property wrappers have an initialValue initializer, the property
55165518
// wrapper will be initialized that way.
5517-
return allAttachedPropertyWrappersHaveInitialValueInit();
5519+
return var->allAttachedPropertyWrappersHaveInitialValueInit();
55185520
}
55195521

5520-
bool VarDecl::isPropertyMemberwiseInitializedWithWrappedType() const {
5521-
auto customAttrs = getAttachedPropertyWrappers();
5522-
if (customAttrs.empty())
5523-
return false;
5524-
5525-
auto *PBD = getParentPatternBinding();
5526-
if (!PBD)
5527-
return false;
5528-
5529-
// If there was an initializer on the original property, initialize
5530-
// via the initial value.
5531-
if (PBD->getPatternList()[0].getEqualLoc().isValid())
5532-
return true;
5533-
5534-
// If there was an initializer on the outermost wrapper, initialize
5535-
// via the full wrapper.
5536-
if (customAttrs[0]->getArg() != nullptr)
5537-
return false;
5522+
bool VarDecl::isPropertyWrapperInitializedWithInitialValue() const {
5523+
return propertyWrapperInitializedViaInitialValue(
5524+
this, /*checkDefaultInit=*/true);
5525+
}
55385526

5539-
// If all property wrappers have an initialValue initializer, the property
5540-
// wrapper will be initialized that way.
5541-
return allAttachedPropertyWrappersHaveInitialValueInit();
5527+
bool VarDecl::isPropertyMemberwiseInitializedWithWrappedType() const {
5528+
return propertyWrapperInitializedViaInitialValue(
5529+
this, /*checkDefaultInit=*/false);
55425530
}
55435531

55445532
Identifier VarDecl::getObjCPropertyName() const {
@@ -5806,25 +5794,71 @@ void ParamDecl::setDefaultArgumentInitContext(Initializer *initContext) {
58065794

58075795
Expr *swift::findOriginalPropertyWrapperInitialValue(VarDecl *var,
58085796
Expr *init) {
5809-
auto attr = var->getAttachedPropertyWrappers().front();
5797+
auto *PBD = var->getParentPatternBinding();
5798+
if (!PBD)
5799+
return nullptr;
58105800

5811-
// Direct initialization implies no original initial value.
5812-
if (attr->getArg())
5801+
// If there is no '=' on the pattern, there was no initial value.
5802+
if (PBD->getPatternList()[0].getEqualLoc().isInvalid())
58135803
return nullptr;
58145804

5815-
// Look through any expressions wrapping the initializer.
5816-
init = init->getSemanticsProvidingExpr();
5817-
auto initCall = dyn_cast<CallExpr>(init);
5818-
if (!initCall)
5805+
ASTContext &ctx = var->getASTContext();
5806+
auto dc = var->getInnermostDeclContext();
5807+
auto innermostAttr = var->getAttachedPropertyWrappers().back();
5808+
auto innermostNominal = evaluateOrDefault(
5809+
ctx.evaluator, CustomAttrNominalRequest{innermostAttr, dc}, nullptr);
5810+
if (!innermostNominal)
58195811
return nullptr;
58205812

5821-
auto initArg = cast<TupleExpr>(initCall->getArg())->getElement(0);
5822-
initArg = initArg->getSemanticsProvidingExpr();
5823-
if (auto autoclosure = dyn_cast<AutoClosureExpr>(initArg)) {
5824-
initArg =
5825-
autoclosure->getSingleExpressionBody()->getSemanticsProvidingExpr();
5826-
}
5813+
// Walker
5814+
class Walker : public ASTWalker {
5815+
public:
5816+
NominalTypeDecl *innermostNominal;
5817+
Expr *initArg = nullptr;
5818+
5819+
Walker(NominalTypeDecl *innermostNominal)
5820+
: innermostNominal(innermostNominal) { }
5821+
5822+
virtual std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
5823+
if (initArg)
5824+
return { false, E };
5825+
5826+
if (auto call = dyn_cast<CallExpr>(E)) {
5827+
// We're looking for an implicit call.
5828+
if (!call->isImplicit())
5829+
return { true, E };
5830+
5831+
// ... producing a value of the same nominal type as the innermost
5832+
// property wrapper.
5833+
if (call->getType()->getAnyNominal() != innermostNominal)
5834+
return { true, E };
5835+
5836+
// Find the implicit initialValue argument.
5837+
if (auto tuple = dyn_cast<TupleExpr>(call->getArg())) {
5838+
ASTContext &ctx = innermostNominal->getASTContext();
5839+
for (unsigned i : range(tuple->getNumElements())) {
5840+
if (tuple->getElementName(i) == ctx.Id_initialValue &&
5841+
tuple->getElementNameLoc(i).isInvalid()) {
5842+
initArg = tuple->getElement(i);
5843+
return { false, E };
5844+
}
5845+
}
5846+
}
5847+
}
58275848

5849+
return { true, E };
5850+
}
5851+
} walker(innermostNominal);
5852+
init->walk(walker);
5853+
5854+
Expr *initArg = walker.initArg;
5855+
if (initArg) {
5856+
initArg = initArg->getSemanticsProvidingExpr();
5857+
if (auto autoclosure = dyn_cast<AutoClosureExpr>(initArg)) {
5858+
initArg =
5859+
autoclosure->getSingleExpressionBody()->getSemanticsProvidingExpr();
5860+
}
5861+
}
58285862
return initArg;
58295863
}
58305864

trunk/lib/Sema/CSSimplify.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4662,7 +4662,8 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
46624662

46634663
// If the base type is optional because we haven't chosen to force an
46644664
// implicit optional, don't try to fix it. The IUO will be forced instead.
4665-
if (auto dotExpr = dyn_cast<UnresolvedDotExpr>(locator->getAnchor())) {
4665+
if (auto dotExpr =
4666+
dyn_cast_or_null<UnresolvedDotExpr>(locator->getAnchor())) {
46664667
auto baseExpr = dotExpr->getBase();
46674668
auto resolvedOverload = getResolvedOverloadSets();
46684669
while (resolvedOverload) {
@@ -4682,8 +4683,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
46824683
auto innerTV = createTypeVariable(locator,
46834684
TVO_CanBindToLValue |
46844685
TVO_CanBindToNoEscape);
4685-
Type optTy = getTypeChecker().getOptionalType(
4686-
locator->getAnchor()->getSourceRange().Start, innerTV);
4686+
Type optTy = getTypeChecker().getOptionalType(SourceLoc(), innerTV);
46874687
SmallVector<Constraint *, 2> optionalities;
46884688
auto nonoptionalResult = Constraint::createFixed(
46894689
*this, ConstraintKind::Bind,

trunk/lib/Sema/TypeCheckPropertyWrapper.cpp

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ using namespace swift;
2828
/// Find the named property in a property wrapper to which access will
2929
/// be delegated.
3030
static VarDecl *findValueProperty(ASTContext &ctx, NominalTypeDecl *nominal,
31-
Identifier name, bool allowMissing) {
31+
Identifier name, bool allowMissing,
32+
bool *diagnosed = nullptr) {
3233
SmallVector<VarDecl *, 2> vars;
3334
{
3435
SmallVector<ValueDecl *, 2> decls;
@@ -49,6 +50,8 @@ static VarDecl *findValueProperty(ASTContext &ctx, NominalTypeDecl *nominal,
4950
if (!allowMissing) {
5051
nominal->diagnose(diag::property_wrapper_no_value_property,
5152
nominal->getDeclaredType(), name);
53+
if (diagnosed)
54+
*diagnosed = true;
5255
}
5356
return nullptr;
5457

@@ -62,6 +65,8 @@ static VarDecl *findValueProperty(ASTContext &ctx, NominalTypeDecl *nominal,
6265
var->diagnose(diag::kind_declname_declared_here,
6366
var->getDescriptiveKind(), var->getFullName());
6467
}
68+
if (diagnosed)
69+
*diagnosed = true;
6570
return nullptr;
6671
}
6772

@@ -72,6 +77,8 @@ static VarDecl *findValueProperty(ASTContext &ctx, NominalTypeDecl *nominal,
7277
var->getFormalAccess(), var->getDescriptiveKind(),
7378
var->getFullName(), nominal->getDeclaredType(),
7479
nominal->getFormalAccess());
80+
if (diagnosed)
81+
*diagnosed = true;
7582
return nullptr;
7683
}
7784

@@ -230,13 +237,32 @@ PropertyWrapperTypeInfoRequest::evaluate(
230237
return PropertyWrapperTypeInfo();
231238
}
232239

233-
// Look for a non-static property named "value" in the property wrapper
234-
// type.
240+
// Look for a non-static property named "wrappedValue" in the property
241+
// wrapper type.
235242
ASTContext &ctx = nominal->getASTContext();
243+
bool diagnosed = false;
236244
auto valueVar =
237-
findValueProperty(ctx, nominal, ctx.Id_value, /*allowMissing=*/false);
238-
if (!valueVar)
239-
return PropertyWrapperTypeInfo();
245+
findValueProperty(ctx, nominal, ctx.Id_wrappedValue,
246+
/*allowMissing=*/true, &diagnosed);
247+
if (!valueVar) {
248+
if (!diagnosed) {
249+
// Look for a non-static property named "value". This is the old name,
250+
// but accept it with a warning.
251+
valueVar = findValueProperty(ctx, nominal, ctx.Id_value,
252+
/*allowMissing=*/true, &diagnosed);
253+
}
254+
255+
if (!valueVar) {
256+
if (!diagnosed) {
257+
valueVar = findValueProperty(ctx, nominal, ctx.Id_wrappedValue,
258+
/*allowMissing=*/false);
259+
}
260+
261+
return PropertyWrapperTypeInfo();
262+
}
263+
264+
valueVar->diagnose(diag::property_wrapper_value);
265+
}
240266

241267
PropertyWrapperTypeInfo result;
242268
result.valueVar = valueVar;

trunk/test/SILGen/property_wrappers.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,60 @@ class UseWrapperWithDefaultInit {
296296
// CHECK: function_ref @$s17property_wrappers22WrapperWithDefaultInitVACyxGycfC
297297
// CHECK: return {{%.*}} : $WrapperWithDefaultInit<String>
298298

299+
// Property wrapper composition.
300+
@propertyWrapper
301+
struct WrapperA<Value> {
302+
var value: Value
303+
304+
init(initialValue: Value) {
305+
value = initialValue
306+
}
307+
}
308+
309+
@propertyWrapper
310+
struct WrapperB<Value> {
311+
var value: Value
312+
313+
init(initialValue: Value) {
314+
value = initialValue
315+
}
316+
}
317+
318+
@propertyWrapper
319+
struct WrapperC<Value> {
320+
var value: Value?
321+
322+
init(initialValue: Value?) {
323+
value = initialValue
324+
}
325+
}
326+
327+
struct CompositionMembers {
328+
// CompositionMembers.p1.getter
329+
// CHECK-LABEL: sil hidden [ossa] @$s17property_wrappers18CompositionMembersV2p1SiSgvg : $@convention(method) (@guaranteed CompositionMembers) -> Optional<Int>
330+
// CHECK: bb0([[SELF:%.*]] : @guaranteed $CompositionMembers):
331+
// CHECK: [[P1:%.*]] = struct_extract [[SELF]] : $CompositionMembers, #CompositionMembers.$p1
332+
// CHECK: [[P1_VALUE:%.*]] = struct_extract [[P1]] : $WrapperA<WrapperB<WrapperC<Int>>>, #WrapperA.value
333+
// CHECK: [[P1_VALUE2:%.*]] = struct_extract [[P1_VALUE]] : $WrapperB<WrapperC<Int>>, #WrapperB.value
334+
// CHECK: [[P1_VALUE3:%.*]] = struct_extract [[P1_VALUE2]] : $WrapperC<Int>, #WrapperC.value
335+
// CHECK: return [[P1_VALUE3]] : $Optional<Int>
336+
@WrapperA @WrapperB @WrapperC var p1: Int?
337+
@WrapperA @WrapperB @WrapperC var p2 = "Hello"
338+
339+
// variable initialization expression of CompositionMembers.$p2
340+
// CHECK-LABEL: sil hidden [transparent] [ossa] @$s17property_wrappers18CompositionMembersV3$p233_{{.*}}8WrapperAVyAA0N1BVyAA0N1CVySSGGGvpfi : $@convention(thin) () -> @owned Optional<String> {
341+
// CHECK: %0 = string_literal utf8 "Hello"
342+
343+
// CHECK-LABEL: sil hidden [ossa] @$s17property_wrappers18CompositionMembersV2p12p2ACSiSg_SSSgtcfC : $@convention(method) (Optional<Int>, @owned Optional<String>, @thin CompositionMembers.Type) -> @owned CompositionMembers
344+
// CHECK: function_ref @$s17property_wrappers8WrapperCV12initialValueACyxGxSg_tcfC
345+
// CHECK: function_ref @$s17property_wrappers8WrapperBV12initialValueACyxGx_tcfC
346+
// CHECK: function_ref @$s17property_wrappers8WrapperAV12initialValueACyxGx_tcfC
347+
}
348+
349+
func testComposition() {
350+
_ = CompositionMembers(p1: nil)
351+
}
352+
299353

300354
// CHECK-LABEL: sil_vtable ClassUsingWrapper {
301355
// CHECK-NEXT: #ClassUsingWrapper.x!getter.1: (ClassUsingWrapper) -> () -> Int : @$s17property_wrappers17ClassUsingWrapperC1xSivg // ClassUsingWrapper.x.getter

trunk/test/SILOptimizer/di_property_wrappers_errors.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
// RUN: %target-swift-frontend -emit-sil -verify %s
22
@propertyWrapper
33
final class ClassWrapper<T> {
4-
var value: T {
4+
var wrappedValue: T {
55
didSet {
6-
print(" .. set \(value)")
6+
print(" .. set \(wrappedValue)")
77
}
88
}
99

1010
init(initialValue: T) {
1111
print(" .. init \(initialValue)")
12-
self.value = initialValue
12+
self.wrappedValue = initialValue
1313
}
1414

1515
deinit {
16-
print(" .. deinit \(value)")
16+
print(" .. deinit \(wrappedValue)")
1717
}
1818
}
1919

trunk/test/decl/protocol/special/coding/property_wrappers_codable.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22

33
@propertyWrapper
44
struct Wrapper<T: Codable> {
5-
var value: T
5+
var wrappedValue: T
66
}
77

88
@propertyWrapper
99
struct WrapperWithInitialValue<T: Codable> {
10-
var value: T
10+
var wrappedValue: T
1111

1212
init(initialValue: T) {
13-
self.value = initialValue
13+
self.wrappedValue = initialValue
1414
}
1515
}
1616

0 commit comments

Comments
 (0)