Skip to content

Commit 093b8d3

Browse files
committed
[Sema] Emit an error for attempts to use @available on var declarations that have attached property wrappers. Availability is not supported on stored properties, and properties with property wrappers are stored properties with a layer of indirection. Also, add the same missing diagnostic for lazy vars.
Resolves rdar://82713248
1 parent e6a1e23 commit 093b8d3

File tree

6 files changed

+47
-5
lines changed

6 files changed

+47
-5
lines changed

include/swift/AST/Decl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5390,6 +5390,10 @@ class VarDecl : public AbstractStorageDecl {
53905390
/// an attached property wrapper.
53915391
VarDecl *getPropertyWrapperWrappedValueVar() const;
53925392

5393+
/// Return true if this property either has storage or has an attached property
5394+
/// wrapper that has storage.
5395+
bool hasStorageOrWrapsStorage() const;
5396+
53935397
/// Visit all auxiliary declarations to this VarDecl.
53945398
///
53955399
/// An auxiliary declaration is a declaration synthesized by the compiler to support

lib/AST/Decl.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6446,6 +6446,20 @@ VarDecl *VarDecl::getPropertyWrapperWrappedValueVar() const {
64466446
return getPropertyWrapperAuxiliaryVariables().localWrappedValueVar;
64476447
}
64486448

6449+
bool VarDecl::hasStorageOrWrapsStorage() const {
6450+
if (hasStorage())
6451+
return true;
6452+
6453+
if (getAttrs().hasAttribute<LazyAttr>())
6454+
return true;
6455+
6456+
auto *backing = getPropertyWrapperBackingProperty();
6457+
if (backing && backing->hasStorage())
6458+
return true;
6459+
6460+
return false;
6461+
}
6462+
64496463
void VarDecl::visitAuxiliaryDecls(llvm::function_ref<void(VarDecl *)> visit) const {
64506464
if (getDeclContext()->isTypeContext() || isImplicit())
64516465
return;

lib/Sema/CodeSynthesis.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -928,10 +928,7 @@ bool AreAllStoredPropertiesDefaultInitableRequest::evaluate(
928928
if (VD->getAttrs().hasAttribute<NSManagedAttr>())
929929
CheckDefaultInitializer = false;
930930

931-
if (VD->hasStorage())
932-
HasStorage = true;
933-
auto *backing = VD->getPropertyWrapperBackingProperty();
934-
if (backing && backing->hasStorage())
931+
if (VD->hasStorageOrWrapsStorage())
935932
HasStorage = true;
936933
});
937934

lib/Sema/TypeCheckAttr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3562,7 +3562,7 @@ TypeChecker::diagnosticIfDeclCannotBePotentiallyUnavailable(const Decl *D) {
35623562
auto *DC = D->getDeclContext();
35633563

35643564
if (auto *VD = dyn_cast<VarDecl>(D)) {
3565-
if (!VD->hasStorage())
3565+
if (!VD->hasStorageOrWrapsStorage())
35663566
return None;
35673567

35683568
// Do not permit potential availability of script-mode global variables;

test/Sema/availability_stored.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,55 @@
88
@available(macOS 50, *)
99
struct NewStruct {}
1010

11+
@available(macOS 50, *)
12+
@propertyWrapper
13+
struct NewPropertyWrapper<Value> {
14+
var wrappedValue: Value
15+
}
16+
1117
@available(macOS 50, *)
1218
struct GoodReferenceStruct {
1319
var x: NewStruct
20+
@NewPropertyWrapper var y: Int
21+
lazy var z: Int = 42
1422
}
1523

1624
@available(macOS 50, *)
1725
struct GoodNestedReferenceStruct {
1826
struct Inner {
1927
var x: NewStruct
28+
@NewPropertyWrapper var y: Int
29+
lazy var z: Int = 42
2030
}
2131
}
2232

2333
struct BadReferenceStruct1 {
2434
// expected-error@+1 {{stored properties cannot be marked potentially unavailable with '@available'}}
2535
@available(macOS 50, *)
2636
var x: NewStruct
37+
38+
// expected-error@+1 {{stored properties cannot be marked potentially unavailable with '@available'}}
39+
@available(macOS 50, *)
40+
@NewPropertyWrapper var y: Int
41+
42+
// expected-error@+1 {{stored properties cannot be marked potentially unavailable with '@available'}}
43+
@available(macOS 50, *)
44+
lazy var z: Int = 42
2745
}
2846

2947
@available(macOS 40, *)
3048
struct BadReferenceStruct2 {
3149
// expected-error@+1 {{stored properties cannot be marked potentially unavailable with '@available'}}
3250
@available(macOS 50, *)
3351
var x: NewStruct
52+
53+
// expected-error@+1 {{stored properties cannot be marked potentially unavailable with '@available'}}
54+
@available(macOS 50, *)
55+
@NewPropertyWrapper var y: Int
56+
57+
// expected-error@+1 {{stored properties cannot be marked potentially unavailable with '@available'}}
58+
@available(macOS 50, *)
59+
lazy var z: Int = 42
3460
}
3561

3662
// The same behavior should hold for enum elements with payloads.

test/decl/class/effectful_properties.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class AcceptableDynamic {
8686
}
8787

8888
// mainly just some sanity checks
89+
// expected-error@+1 {{class 'Misc' has no initializers}}
8990
class Misc {
9091
// expected-error@+2 {{'lazy' cannot be used on a computed property}}
9192
// expected-error@+1 {{lazy properties must have an initializer}}

0 commit comments

Comments
 (0)