Skip to content

Commit 21837e9

Browse files
committed
Sema: Reject @available on observing accessors.
Marking an observer unavailable (or potentially unavailable) has no effect since the compiler emits calls to them unconditionally. Resolves rdar://80337141.
1 parent 5f31a2b commit 21837e9

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

lib/Sema/TypeCheckAttr.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4932,6 +4932,12 @@ TypeChecker::diagnosticIfDeclCannotBePotentiallyUnavailable(const Decl *D) {
49324932
if (auto *DD = dyn_cast<DestructorDecl>(D))
49334933
return Diagnostic(diag::availability_decl_no_potential, D);
49344934

4935+
// Observing accessors are always called implicitly.
4936+
if (auto *AD = dyn_cast<AccessorDecl>(D)) {
4937+
if (AD->isObservingAccessor())
4938+
return Diagnostic(diag::availability_decl_no_potential, D);
4939+
}
4940+
49354941
if (auto *VD = dyn_cast<VarDecl>(D)) {
49364942
if (!VD->hasStorageOrWrapsStorage())
49374943
return std::nullopt;
@@ -4987,6 +4993,12 @@ TypeChecker::diagnosticIfDeclCannotBeUnavailable(const Decl *D) {
49874993
if (auto *AT = dyn_cast<AssociatedTypeDecl>(D))
49884994
return Diagnostic(diag::availability_decl_no_unavailable, D);
49894995

4996+
// Observing accessors are always called implicitly.
4997+
if (auto *AD = dyn_cast<AccessorDecl>(D)) {
4998+
if (AD->isObservingAccessor())
4999+
return Diagnostic(diag::availability_decl_no_unavailable, D);
5000+
}
5001+
49905002
if (auto *VD = dyn_cast<VarDecl>(D)) {
49915003
if (!VD->hasStorageOrWrapsStorage())
49925004
return std::nullopt;

test/Sema/availability_accessors.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ struct SubscriptHelper {
9898
@available(*, unavailable)
9999
set { } // expected-note {{setter for 'subscript(unavailableGetterAndSetter:)' has been explicitly marked unavailable here}}
100100
}
101-
102101
}
103102

104103
@discardableResult func takesInOut<T>(_ t: inout T) -> T {
@@ -553,3 +552,22 @@ struct TestPatternBindingInitExprs {
553552
var unavailableGetterAndSetter_0 = global.unavailableGetterAndSetter[0] // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
554553
var unavailableGetterAndSetter_0_b = global.unavailableGetterAndSetter[0].b // expected-error {{getter for 'unavailableGetterAndSetter' is unavailable}}
555554
}
555+
556+
struct BadAccessorAvailability<T> {
557+
var alwaysUnavailableObservers: T {
558+
@available(*, unavailable) // expected-error {{willSet observer for property cannot be marked unavailable with '@available'}}
559+
willSet { }
560+
561+
@available(*, unavailable) // expected-error {{didSet observer for property cannot be marked unavailable with '@available'}}
562+
didSet { }
563+
}
564+
565+
var observersUnavailableBeforeSwift99: T {
566+
@available(swift, introduced: 99) // expected-error {{willSet observer for property cannot be marked unavailable with '@available'}}
567+
willSet { }
568+
569+
@available(swift, introduced: 99) // expected-error {{didSet observer for property cannot be marked unavailable with '@available'}}
570+
didSet { }
571+
}
572+
573+
}

test/Sema/availability_versions.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,3 +1801,21 @@ class StoredPropertiesWithAvailabilityInClosures {
18011801
return 0
18021802
}()
18031803
}
1804+
1805+
struct PropertyObservers {
1806+
var hasPotentiallyUnavailableObservers: Int {
1807+
@available(macOS 51, *) // expected-error {{willSet observer for property cannot be marked potentially unavailable with '@available'}}
1808+
willSet { }
1809+
1810+
@available(macOS 51, *) // expected-error {{didSet observer for property cannot be marked potentially unavailable with '@available'}}
1811+
didSet { }
1812+
}
1813+
1814+
var hasObsoletedObservers: Int {
1815+
@available(macOS, obsoleted: 10.9) // expected-error {{willSet observer for property cannot be marked unavailable with '@available'}}
1816+
willSet { }
1817+
1818+
@available(macOS, obsoleted: 10.9) // expected-error {{didSet observer for property cannot be marked unavailable with '@available'}}
1819+
didSet { }
1820+
}
1821+
}

0 commit comments

Comments
 (0)