Skip to content

Commit 5db6280

Browse files
authored
Merge pull request #25424 from DougGregor/property-wrapper-attr-rename-5.1-06-12-2019
[5.1 2019-06-12] [Type checker] Compute correct contextual substitutions for local generics
2 parents 7b82d01 + a6e78f9 commit 5db6280

25 files changed

+210
-91
lines changed

include/swift/AST/Attr.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ SIMPLE_DECL_ATTR(_implementationOnly, ImplementationOnly,
400400
DECL_ATTR(_custom, Custom,
401401
OnAnyDecl | UserInaccessible,
402402
85)
403-
SIMPLE_DECL_ATTR(_propertyWrapper, PropertyWrapper,
403+
SIMPLE_DECL_ATTR(propertyWrapper, PropertyWrapper,
404404
OnStruct | OnClass | OnEnum,
405405
86)
406406
SIMPLE_DECL_ATTR(_disfavoredOverload, DisfavoredOverload,

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5125,6 +5125,10 @@ class VarDecl : public AbstractStorageDecl {
51255125
/// \end
51265126
bool isPropertyWrapperInitializedWithInitialValue() const;
51275127

5128+
/// Whether the memberwise initializer parameter for a property with a property wrapper type
5129+
/// uses the wrapped type.
5130+
bool isPropertyMemberwiseInitializedWithWrappedType() const;
5131+
51285132
/// If this property is the backing storage for a property with an attached
51295133
/// property wrapper, return the original property.
51305134
///

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4440,6 +4440,9 @@ ERROR(property_wrapper_type_not_usable_from_inline,none,
44404440
"%select{%select{variable|constant}0|property}1 "
44414441
"must be '@usableFromInline' or public",
44424442
(bool, bool))
4443+
WARNING(property_wrapper_delegateValue,none,
4444+
"property wrapper's `delegateValue` property should be renamed to "
4445+
"'wrapperValue'; use of 'delegateValue' is deprecated", ())
44434446

44444447
//------------------------------------------------------------------------------
44454448
// MARK: function builder diagnostics

lib/AST/Decl.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5397,10 +5397,6 @@ VarDecl *VarDecl::getPropertyWrapperBackingProperty() const {
53975397
}
53985398

53995399
bool VarDecl::isPropertyWrapperInitializedWithInitialValue() const {
5400-
auto &ctx = getASTContext();
5401-
if (!ctx.getLazyResolver())
5402-
return false;
5403-
54045400
auto customAttr = getAttachedPropertyWrapper();
54055401
if (!customAttr)
54065402
return false;
@@ -5419,9 +5415,33 @@ bool VarDecl::isPropertyWrapperInitializedWithInitialValue() const {
54195415
if (customAttr->getArg() != nullptr)
54205416
return false;
54215417

5422-
// If the property wrapper is default-initializable, it's the wrapper
5423-
// being initialized.
5424-
if (PBD->isDefaultInitializable(0))
5418+
// Default initialization does not use a value.
5419+
auto wrapperTypeInfo = getAttachedPropertyWrapperTypeInfo();
5420+
if (wrapperTypeInfo.defaultInit)
5421+
return false;
5422+
5423+
// There is no initializer, so the initialization form depends on
5424+
// whether the property wrapper type has an init(initialValue:).
5425+
return wrapperTypeInfo.initialValueInit != nullptr;
5426+
}
5427+
5428+
bool VarDecl::isPropertyMemberwiseInitializedWithWrappedType() const {
5429+
auto customAttr = getAttachedPropertyWrapper();
5430+
if (!customAttr)
5431+
return false;
5432+
5433+
auto *PBD = getParentPatternBinding();
5434+
if (!PBD)
5435+
return false;
5436+
5437+
// If there was an initializer on the original property, initialize
5438+
// via the initial value.
5439+
if (PBD->getPatternList()[0].getEqualLoc().isValid())
5440+
return true;
5441+
5442+
// If there was an initializer on the attribute itself, initialize
5443+
// via the full wrapper.
5444+
if (customAttr->getArg() != nullptr)
54255445
return false;
54265446

54275447
// There is no initializer, so the initialization form depends on

lib/Parse/ParseDecl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1800,6 +1800,12 @@ ParserStatus Parser::parseDeclAttribute(DeclAttributes &Attributes, SourceLoc At
18001800
checkInvalidAttrName("_inlineable", "inlinable", DAK_Inlinable);
18011801
}
18021802

1803+
// Other names of property wrappers...
1804+
checkInvalidAttrName("propertyDelegate", "propertyWrapper",
1805+
DAK_PropertyWrapper, diag::attr_renamed_warning);
1806+
checkInvalidAttrName("_propertyWrapper", "propertyWrapper",
1807+
DAK_PropertyWrapper, diag::attr_renamed_warning);
1808+
18031809
if (DK == DAK_Count && Tok.getText() == "warn_unused_result") {
18041810
// The behavior created by @warn_unused_result is now the default. Emit a
18051811
// Fix-It to remove.

lib/SILGen/SILGen.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,10 +1120,13 @@ emitStoredPropertyInitialization(PatternBindingDecl *pbd, unsigned i) {
11201120
// If this is the backing storage for a property with an attached wrapper
11211121
// that was initialized with `=`, use that expression as the initializer.
11221122
if (auto originalProperty = var->getOriginalWrappedProperty()) {
1123-
auto wrapperInfo =
1124-
originalProperty->getPropertyWrapperBackingPropertyInfo();
1125-
if (wrapperInfo.originalInitialValue)
1126-
init = wrapperInfo.originalInitialValue;
1123+
if (originalProperty
1124+
->isPropertyMemberwiseInitializedWithWrappedType()) {
1125+
auto wrapperInfo =
1126+
originalProperty->getPropertyWrapperBackingPropertyInfo();
1127+
if (wrapperInfo.originalInitialValue)
1128+
init = wrapperInfo.originalInitialValue;
1129+
}
11271130
}
11281131

11291132
SILDeclRef constant(var, SILDeclRef::Kind::StoredPropertyInitializer);

lib/SILGen/SILGenConstructor.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ static bool maybeEmitPropertyWrapperInitFromValue(
112112
llvm::function_ref<void(Expr *)> body) {
113113
auto originalProperty = field->getOriginalWrappedProperty();
114114
if (!originalProperty ||
115-
!originalProperty->isPropertyWrapperInitializedWithInitialValue())
115+
!originalProperty->isPropertyMemberwiseInitializedWithWrappedType())
116116
return false;
117117

118118
auto wrapperInfo = originalProperty->getPropertyWrapperBackingPropertyInfo();
@@ -991,11 +991,15 @@ void SILGenFunction::emitMemberInitializers(DeclContext *dc,
991991
// property wrapper initialized with `=`, inject the value into an
992992
// instance of the wrapper.
993993
if (auto singleVar = pbd->getSingleVar()) {
994-
(void)maybeEmitPropertyWrapperInitFromValue(
995-
*this, init, singleVar, std::move(result),
996-
[&](Expr *expr) {
997-
result = emitRValue(expr);
998-
});
994+
auto originalVar = singleVar->getOriginalWrappedProperty();
995+
if (originalVar &&
996+
originalVar->isPropertyWrapperInitializedWithInitialValue()) {
997+
(void)maybeEmitPropertyWrapperInitFromValue(
998+
*this, init, singleVar, std::move(result),
999+
[&](Expr *expr) {
1000+
result = emitRValue(expr);
1001+
});
1002+
}
9991003
}
10001004

10011005
emitMemberInit(*this, selfDecl, entry.getPattern(), std::move(result));

lib/Sema/CodeSynthesis.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2070,12 +2070,18 @@ static void maybeAddMemberwiseDefaultArg(ParamDecl *arg, VarDecl *var,
20702070
if (!var->getParentPattern()->getSingleVar())
20712071
return;
20722072

2073-
// If we don't have an expression initializer or silgen can't assign a default
2074-
// initializer, then we can't generate a default value. An example of where
2075-
// silgen can assign a default is var x: Int? where the default is nil.
2076-
// If the variable is lazy, go ahead and give it a default value.
2077-
if (!var->getAttrs().hasAttribute<LazyAttr>() &&
2078-
!var->getParentPatternBinding()->isDefaultInitializable())
2073+
// Determine whether this variable will be 'nil' initialized.
2074+
bool isNilInitialized =
2075+
(isa<OptionalType>(var->getValueInterfaceType().getPointer()) &&
2076+
!var->isParentInitialized()) ||
2077+
var->getAttrs().hasAttribute<LazyAttr>();
2078+
2079+
// Whether we have explicit initialization.
2080+
bool isExplicitlyInitialized = var->isParentInitialized();
2081+
2082+
// If this is neither nil-initialized nor explicitly initialized, don't add
2083+
// anything.
2084+
if (!isNilInitialized && !isExplicitlyInitialized)
20792085
return;
20802086

20812087
// We can add a default value now.
@@ -2091,13 +2097,14 @@ static void maybeAddMemberwiseDefaultArg(ParamDecl *arg, VarDecl *var,
20912097
// default arg. All lazy variables return a nil literal as well. *Note* that
20922098
// the type will always be a sugared T? because we don't default init an
20932099
// explicit Optional<T>.
2094-
if ((isa<OptionalType>(var->getValueInterfaceType().getPointer()) &&
2095-
!var->isParentInitialized()) ||
2096-
var->getAttrs().hasAttribute<LazyAttr>()) {
2100+
if (isNilInitialized) {
20972101
arg->setDefaultArgumentKind(DefaultArgumentKind::NilLiteral);
20982102
return;
20992103
}
21002104

2105+
// Explicitly initialize.
2106+
assert(isExplicitlyInitialized);
2107+
21012108
// If there's a backing storage property, the memberwise initializer
21022109
// will be in terms of that.
21032110
VarDecl *backingStorageVar = var->getPropertyWrapperBackingProperty();
@@ -2157,7 +2164,7 @@ ConstructorDecl *swift::createImplicitConstructor(TypeChecker &tc,
21572164
// accept a value of the original property type. Otherwise, the
21582165
// memberwise initializer will be in terms of the backing storage
21592166
// type.
2160-
if (!var->isPropertyWrapperInitializedWithInitialValue()) {
2167+
if (!var->isPropertyMemberwiseInitializedWithWrappedType()) {
21612168
varInterfaceType = backingPropertyType;
21622169
}
21632170
}

lib/Sema/TypeCheckPropertyWrapper.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ static ConstructorDecl *findDefaultInit(ASTContext &ctx,
225225
llvm::Expected<PropertyWrapperTypeInfo>
226226
PropertyWrapperTypeInfoRequest::evaluate(
227227
Evaluator &eval, NominalTypeDecl *nominal) const {
228-
// We must have the @_propertyWrapper attribute to continue.
228+
// We must have the @propertyWrapper attribute to continue.
229229
if (!nominal->getAttrs().hasAttribute<PropertyWrapperAttr>()) {
230230
return PropertyWrapperTypeInfo();
231231
}
@@ -245,6 +245,18 @@ PropertyWrapperTypeInfoRequest::evaluate(
245245
result.wrapperValueVar =
246246
findValueProperty(ctx, nominal, ctx.Id_wrapperValue, /*allowMissing=*/true);
247247

248+
// If there was no wrapperValue property, but there is a delegateValue
249+
// property, use that and warn.
250+
if (!result.wrapperValueVar) {
251+
result.wrapperValueVar =
252+
findValueProperty(ctx, nominal, ctx.Id_delegateValue,
253+
/*allowMissing=*/true);
254+
if (result.wrapperValueVar) {
255+
result.wrapperValueVar->diagnose(diag::property_wrapper_delegateValue)
256+
.fixItReplace(result.wrapperValueVar->getNameLoc(), "wrapperValue");
257+
}
258+
}
259+
248260
return result;
249261
}
250262

@@ -259,7 +271,7 @@ AttachedPropertyWrapperRequest::evaluate(Evaluator &evaluator,
259271
auto nominal = evaluateOrDefault(
260272
ctx.evaluator, CustomAttrNominalRequest{mutableAttr, dc}, nullptr);
261273

262-
// If we didn't find a nominal type with a @_propertyWrapper attribute,
274+
// If we didn't find a nominal type with a @propertyWrapper attribute,
263275
// skip this custom attribute.
264276
if (!nominal || !nominal->getAttrs().hasAttribute<PropertyWrapperAttr>())
265277
continue;

lib/Sema/TypeCheckType.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,6 +821,13 @@ Type TypeChecker::applyUnboundGenericArguments(
821821

822822
subs = parentType->getContextSubstitutions(decl->getDeclContext());
823823
skipRequirementsCheck |= parentType->hasTypeVariable();
824+
} else if (auto genericEnv =
825+
decl->getDeclContext()->getGenericEnvironmentOfContext()) {
826+
auto subMap = genericEnv->getForwardingSubstitutionMap();
827+
for (auto gp : subMap.getGenericSignature()->getGenericParams()) {
828+
subs[gp->getCanonicalType()->castTo<GenericTypeParamType>()] =
829+
Type(gp).subst(subMap);
830+
}
824831
}
825832

826833
SourceLoc noteLoc = decl->getLoc();

test/IDE/complete_decl_attribute.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class C {}
7575
// KEYWORD3-NEXT: Keyword/None: objcMembers[#Class Attribute#]; name=objcMembers{{$}}
7676
// KEYWORD3-NEXT: Keyword/None: NSApplicationMain[#Class Attribute#]; name=NSApplicationMain{{$}}
7777
// KEYWORD3-NEXT: Keyword/None: usableFromInline[#Class Attribute#]; name=usableFromInline
78-
// KEYWORD3-NEXT: Keyword/None: _propertyWrapper[#Class Attribute#]; name=_propertyWrapper
78+
// KEYWORD3-NEXT: Keyword/None: propertyWrapper[#Class Attribute#]; name=propertyWrapper
7979
// KEYWORD3-NEXT: Keyword/None: _functionBuilder[#Class Attribute#]; name=_functionBuilder
8080
// KEYWORD3-NEXT: End completions
8181

@@ -91,7 +91,7 @@ enum E {}
9191
// KEYWORD4-NEXT: Keyword/None: dynamicCallable[#Enum Attribute#]; name=dynamicCallable
9292
// KEYWORD4-NEXT: Keyword/None: dynamicMemberLookup[#Enum Attribute#]; name=dynamicMemberLookup
9393
// KEYWORD4-NEXT: Keyword/None: usableFromInline[#Enum Attribute#]; name=usableFromInline
94-
// KEYWORD4-NEXT: Keyword/None: _propertyWrapper[#Enum Attribute#]; name=_propertyWrapper
94+
// KEYWORD4-NEXT: Keyword/None: propertyWrapper[#Enum Attribute#]; name=propertyWrapper
9595
// KEYWORD4-NEXT: Keyword/None: _functionBuilder[#Enum Attribute#]; name=_functionBuilder
9696
// KEYWORD4-NEXT: End completions
9797

@@ -103,7 +103,7 @@ struct S{}
103103
// KEYWORD5-NEXT: Keyword/None: dynamicCallable[#Struct Attribute#]; name=dynamicCallable
104104
// KEYWORD5-NEXT: Keyword/None: dynamicMemberLookup[#Struct Attribute#]; name=dynamicMemberLookup
105105
// KEYWORD5-NEXT: Keyword/None: usableFromInline[#Struct Attribute#]; name=usableFromInline
106-
// KEYWORD5-NEXT: Keyword/None: _propertyWrapper[#Struct Attribute#]; name=_propertyWrapper
106+
// KEYWORD5-NEXT: Keyword/None: propertyWrapper[#Struct Attribute#]; name=propertyWrapper
107107
// KEYWORD5-NEXT: Keyword/None: _functionBuilder[#Struct Attribute#]; name=_functionBuilder
108108
// KEYWORD5-NEXT: End completions
109109

@@ -204,7 +204,7 @@ struct _S {
204204
// ON_MEMBER_LAST-DAG: Keyword/None: discardableResult[#Declaration Attribute#]; name=discardableResult
205205
// ON_MEMBER_LAST-DAG: Keyword/None: GKInspectable[#Declaration Attribute#]; name=GKInspectable
206206
// ON_MEMBER_LAST-DAG: Keyword/None: IBSegueAction[#Declaration Attribute#]; name=IBSegueAction
207-
// ON_MEMBER_LAST-DAG: Keyword/None: _propertyWrapper[#Declaration Attribute#]; name=_propertyWrapper
207+
// ON_MEMBER_LAST-DAG: Keyword/None: propertyWrapper[#Declaration Attribute#]; name=propertyWrapper
208208
// ON_MEMBER_LAST-DAG: Keyword/None: _functionBuilder[#Declaration Attribute#]; name=_functionBuilder
209209
// ON_MEMBER_LAST-NOT: Keyword
210210
// ON_MEMBER_LAST: Decl[Struct]/CurrModule: MyStruct[#MyStruct#]; name=MyStruct
@@ -236,7 +236,7 @@ struct _S {
236236
// KEYWORD_LAST-NEXT: Keyword/None: usableFromInline[#Declaration Attribute#]; name=usableFromInline{{$}}
237237
// KEYWORD_LAST-NEXT: Keyword/None: discardableResult[#Declaration Attribute#]; name=discardableResult
238238
// KEYWORD_LAST-NEXT: Keyword/None: GKInspectable[#Declaration Attribute#]; name=GKInspectable{{$}}
239-
// KEYWORD_LAST-NEXT: Keyword/None: _propertyWrapper[#Declaration Attribute#]; name=_propertyWrapper
239+
// KEYWORD_LAST-NEXT: Keyword/None: propertyWrapper[#Declaration Attribute#]; name=propertyWrapper
240240
// KEYWORD_LAST-NEXT: Keyword/None: _functionBuilder[#Declaration Attribute#]; name=_functionBuilder{{$}}
241241
// KEYWORD_LAST-NEXT: Keyword/None: IBSegueAction[#Declaration Attribute#]; name=IBSegueAction{{$}}
242242
// KEYWORD_LAST-NOT: Keyword

test/IDE/complete_property_delegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=SELF_VARNAME | %FileCheck %s -check-prefix=CONTEXT_VARNAME
77
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=SELF_DOLLAR_VARNAME | %FileCheck %s -check-prefix=CONTEXT_DOLLAR_VARNAME
88

9-
@_propertyWrapper
9+
@propertyWrapper
1010
struct Lazzzy<T> {
1111
var value: T
1212

test/IDE/complete_property_delegate_attribute.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ enum MyEnum {
66
case east, west
77
}
88

9-
@_propertyWrapper
9+
@propertyWrapper
1010
struct MyStruct {
1111
var value: MyEnum
1212
init(initialValue: MyEnum) {}

test/IDE/print_property_wrappers.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Directly printing the type-checked AST
44
// RUN: %target-swift-ide-test -print-ast-typechecked -source-filename %s | %FileCheck %s
55

6-
@_propertyWrapper
6+
@propertyWrapper
77
struct Wrapper<Value> {
88
var _stored: Value?
99

@@ -47,9 +47,9 @@ struct HasWrappers {
4747
var z: String
4848

4949
// Memberwise initializer.
50-
// CHECK: init(x: Wrapper<Int> = Wrapper(closure: foo), y: Bool = true, z: Wrapper<String> = Wrapper())
50+
// CHECK: init(x: Wrapper<Int> = Wrapper(closure: foo), y: Bool = true, z: String)
5151
}
5252

5353
func trigger() {
54-
_ = HasWrappers(y: false)
54+
_ = HasWrappers(y: false, z: "hello")
5555
}

test/Index/property_wrappers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %target-swift-ide-test -print-indexed-symbols -source-filename %s | %FileCheck -check-prefix=CHECK %s
22

3-
@_propertyWrapper
3+
@propertyWrapper
44
public struct Wrapper<T> {
55
public var value: T
66

test/ParseableInterface/property_wrappers.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
// RUN: %target-swift-frontend -build-module-from-parseable-interface -swift-version 5 %t/TestResilient.swiftinterface -o %t/TestResilient.swiftmodule
77
// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules -swift-version 5 -emit-parseable-module-interface-path - %t/TestResilient.swiftmodule -module-name TestResilient | %FileCheck %s --check-prefix CHECK --check-prefix RESILIENT
88

9-
@_propertyWrapper
9+
@propertyWrapper
1010
public struct Wrapper<T> {
1111
public var value: T
1212
}
1313

14-
@_propertyWrapper
14+
@propertyWrapper
1515
public struct WrapperWithInitialValue<T> {
1616
public var value: T
1717

test/SILGen/property_wrappers.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// RUN: %target-swift-frontend -primary-file %s -emit-silgen | %FileCheck %s
22
// FIXME: switch to %target-swift-emit-silgen once we have syntax tree support
33

4-
@_propertyWrapper
4+
@propertyWrapper
55
struct Wrapper<T> {
66
var value: T
77
}
88

9-
@_propertyWrapper
9+
@propertyWrapper
1010
struct WrapperWithInitialValue<T> {
1111
var value: T
1212

@@ -107,7 +107,7 @@ func forceHasMemberwiseInit() {
107107
// CHECK: bb0:
108108
// CHECK: function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF
109109
struct HasNested<T> {
110-
@_propertyWrapper
110+
@propertyWrapper
111111
private struct PrivateWrapper<U> {
112112
var value: U
113113
init(initialValue: U) {
@@ -180,7 +180,7 @@ struct WrapperWithDidSetWillSet {
180180
}
181181
}
182182

183-
@_propertyWrapper
183+
@propertyWrapper
184184
struct WrapperWithStorageValue<T> {
185185
var value: T
186186

@@ -201,7 +201,7 @@ struct UseWrapperWithStorageValue {
201201
}
202202
}
203203

204-
@_propertyWrapper
204+
@propertyWrapper
205205
enum Lazy<Value> {
206206
case uninitialized(() -> Value)
207207
case initialized(Value)
@@ -270,7 +270,7 @@ extension ClassUsingWrapper {
270270
}
271271

272272
//
273-
@_propertyWrapper
273+
@propertyWrapper
274274
struct WrapperWithDefaultInit<T> {
275275
private var storage: T?
276276

0 commit comments

Comments
 (0)