Files
swift-mirror/test/Availability/property_wrapper_availability.swift
Allan Shortlidge 4d41db3b5d Sema: Rationalize availability checking in unavailable contexts.
Correct several behaviors of availability checking in unavailable contexts that
were inconsistent with the checking model:

- Avoid diagnosing unintroduced and obsolted declarations in contexts that are
  unavailable in the same domain.
- Diagnose unavailability normally in type signature contexts.
2025-08-08 07:57:44 -07:00

222 lines
8.9 KiB
Swift

// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx50
// REQUIRES: OS=macosx
struct S {}
@propertyWrapper
struct AlwaysAvailableWrapper<T> {
var wrappedValue: T
}
@available(macOS 51, *)
@propertyWrapper
struct Available51Wrapper<T> {
var wrappedValue: T
}
@available(*, deprecated)
@propertyWrapper
struct DeprecatedWrapper<T> {
var wrappedValue: T
}
@available(*, unavailable)
@propertyWrapper
struct UnavailableWrapper<T> { // expected-note 12 {{'UnavailableWrapper' has been explicitly marked unavailable here}}
var wrappedValue: T
}
@propertyWrapper
struct WrappedValueUnavailableOnMacOS<T> {
init(wrappedValue: T) { fatalError() }
@available(macOS, unavailable)
var wrappedValue: T { // expected-note 6 {{'wrappedValue' has been explicitly marked unavailable here}}
get { fatalError() }
set { fatalError() }
}
}
@propertyWrapper
struct WrappedValueAvailable51<T> {
init(wrappedValue: T) { fatalError() }
@available(macOS 51, *)
var wrappedValue: T {
get { fatalError() }
set { fatalError() }
}
}
struct AlwaysAvailableStruct { // expected-note 3 {{add '@available' attribute to enclosing struct}}
@AlwaysAvailableWrapper var alwaysAvailableExplicit: S
@AlwaysAvailableWrapper var alwaysAvailableInferred = S()
@Available51Wrapper var available51Explicit: S // expected-error {{'Available51Wrapper' is only available in macOS 51 or newer}}
@Available51Wrapper var available51Inferred = S() // expected-error {{'Available51Wrapper' is only available in macOS 51 or newer}}
@DeprecatedWrapper var deprecatedExplicit: S // expected-warning {{'DeprecatedWrapper' is deprecated}}
@DeprecatedWrapper var deprecatedInferred = S() // expected-warning {{'DeprecatedWrapper' is deprecated}}
@UnavailableWrapper var unavailableExplicit: S // expected-error {{'UnavailableWrapper' is unavailable}}
@UnavailableWrapper var unavailableInferred = S() // expected-error {{'UnavailableWrapper' is unavailable}}
@WrappedValueUnavailableOnMacOS var unavailableWrappedValue: S // expected-error {{'wrappedValue' is unavailable in macOS}}
@WrappedValueAvailable51 var wrappedValueAavailable51: S // expected-error {{'wrappedValue' is only available in macOS 51 or newer}}
}
@available(macOS 51, *)
struct Available51Struct {
@AlwaysAvailableWrapper var alwaysAvailableExplicit: S
@AlwaysAvailableWrapper var alwaysAvailableInferred = S()
@Available51Wrapper var available51Explicit: S
@Available51Wrapper var available51Inferred = S()
@DeprecatedWrapper var deprecatedExplicit: S // expected-warning {{'DeprecatedWrapper' is deprecated}}
@DeprecatedWrapper var deprecatedInferred = S() // expected-warning {{'DeprecatedWrapper' is deprecated}}
@UnavailableWrapper var unavailableExplicit: S // expected-error {{'UnavailableWrapper' is unavailable}}
@UnavailableWrapper var unavailableInferred = S() // expected-error {{'UnavailableWrapper' is unavailable}}
@WrappedValueUnavailableOnMacOS var unavailableWrappedValue: S // expected-error {{'wrappedValue' is unavailable in macOS}}
@WrappedValueAvailable51 var wrappedValueAavailable51: S
}
@available(*, unavailable)
struct UnavailableStruct {
@AlwaysAvailableWrapper var alwaysAvailableExplicit: S
@AlwaysAvailableWrapper var alwaysAvailableInferred = S()
@Available51Wrapper var available51Explicit: S
@Available51Wrapper var available51Inferred = S()
@DeprecatedWrapper var deprecatedExplicit: S
@DeprecatedWrapper var deprecatedInferred = S()
@UnavailableWrapper var unavailableExplicit: S
@UnavailableWrapper var unavailableInferred = S()
@WrappedValueUnavailableOnMacOS var unavailableWrappedValue: S
@WrappedValueAvailable51 var wrappedValueAavailable51: S
}
@available(macOS, unavailable)
struct UnavailableOnMacOSStruct {
@AlwaysAvailableWrapper var alwaysAvailableExplicit: S
@AlwaysAvailableWrapper var alwaysAvailableInferred = S()
@Available51Wrapper var available51Explicit: S
@Available51Wrapper var available51Inferred = S()
@DeprecatedWrapper var deprecatedExplicit: S
@DeprecatedWrapper var deprecatedInferred = S()
@UnavailableWrapper var unavailableExplicit: S // expected-error {{'UnavailableWrapper' is unavailable}}
@UnavailableWrapper var unavailableInferred = S() // expected-error {{'UnavailableWrapper' is unavailable}}
@WrappedValueUnavailableOnMacOS var unavailableWrappedValue: S
@WrappedValueAvailable51 var wrappedValueAavailable51: S
}
func alwaysAvailableFunc( // expected-note 4 {{add '@available' attribute to enclosing global function}}
@AlwaysAvailableWrapper _ alwaysAvailable: S,
@Available51Wrapper _ available51: S, // expected-error {{'Available51Wrapper' is only available in macOS 51 or newer}}
@DeprecatedWrapper _ deprecated: S, // expected-warning {{'DeprecatedWrapper' is deprecated}}
@UnavailableWrapper _ unavailable: S, // expected-error {{'UnavailableWrapper' is unavailable}}
@WrappedValueUnavailableOnMacOS _ unavailableWrappedValue: S, // expected-error {{'wrappedValue' is unavailable in macOS}}
@WrappedValueAvailable51 _ wrappedValueAavailable51: S // expected-error {{'wrappedValue' is only available in macOS 51 or newer}}
) {
@AlwaysAvailableWrapper var alwaysAvailableLocal = S()
@Available51Wrapper var available51Local = S() // expected-error {{'Available51Wrapper' is only available in macOS 51 or newer}}
@DeprecatedWrapper var deprecatedLocal = S() // expected-warning {{'DeprecatedWrapper' is deprecated}}
@UnavailableWrapper var unavailableLocal = S() // expected-error {{'UnavailableWrapper' is unavailable}}
@WrappedValueUnavailableOnMacOS var unavailableWrappedValueLocal = S() // expected-error {{'wrappedValue' is unavailable}}
@WrappedValueAvailable51 var wrappedValueAavailable51 = S() // expected-error {{'wrappedValue' is only available in macOS 51 or newer}}
}
@available(macOS 51, *)
func available51Func(
@AlwaysAvailableWrapper _ alwaysAvailable: S,
@Available51Wrapper _ available51: S,
@DeprecatedWrapper _ deprecated: S, // expected-warning {{'DeprecatedWrapper' is deprecated}}
@UnavailableWrapper _ unavailable: S, // expected-error {{'UnavailableWrapper' is unavailable}}
@WrappedValueUnavailableOnMacOS _ unavailableWrappedValue: S, // expected-error {{'wrappedValue' is unavailable in macOS}}
@WrappedValueAvailable51 _ wrappedValueAavailable51: S
) {
@AlwaysAvailableWrapper var alwaysAvailableLocal = S()
@Available51Wrapper var available51Local = S()
@DeprecatedWrapper var deprecatedLocal = S() // expected-warning {{'DeprecatedWrapper' is deprecated}}
@UnavailableWrapper var unavailableLocal = S() // expected-error {{'UnavailableWrapper' is unavailable}}
@WrappedValueUnavailableOnMacOS var unavailableWrappedValueLocal = S() // expected-error {{'wrappedValue' is unavailable}}
@WrappedValueAvailable51 var wrappedValueAavailable51 = S()
}
@available(*, unavailable)
func unavailableFunc(
@AlwaysAvailableWrapper _ alwaysAvailable: S,
@Available51Wrapper _ available51: S,
@DeprecatedWrapper _ deprecated: S,
@UnavailableWrapper _ unavailable: S,
@WrappedValueUnavailableOnMacOS _ unavailableWrappedValue: S,
@WrappedValueAvailable51 _ wrappedValueAavailable51: S
) {
@AlwaysAvailableWrapper var alwaysAvailableLocal = S()
@Available51Wrapper var available51Local = S()
@DeprecatedWrapper var deprecatedLocal = S()
@UnavailableWrapper var unavailableLocal = S()
@WrappedValueUnavailableOnMacOS var unavailableWrappedValueLocal = S()
@WrappedValueAvailable51 var wrappedValueAavailable51 = S()
}
@available(macOS, unavailable)
func unavailableOnMacOSFunc(
@AlwaysAvailableWrapper _ alwaysAvailable: S,
@Available51Wrapper _ available51: S,
@DeprecatedWrapper _ deprecated: S,
@UnavailableWrapper _ unavailable: S, // expected-error {{'UnavailableWrapper' is unavailable}}
@WrappedValueUnavailableOnMacOS _ unavailableWrappedValue: S,
@WrappedValueAvailable51 _ wrappedValueAavailable51: S
) {
@AlwaysAvailableWrapper var alwaysAvailableLocal = S()
@Available51Wrapper var available51Local = S()
@DeprecatedWrapper var deprecatedLocal = S()
@UnavailableWrapper var unavailableLocal = S() // expected-error {{'UnavailableWrapper' is unavailable}}
@WrappedValueUnavailableOnMacOS var unavailableWrappedValueLocal = S()
@WrappedValueAvailable51 var wrappedValueAavailable51 = S()
}
@propertyWrapper
struct Observable<Value> {
private var stored: Value
init(wrappedValue: Value) {
self.stored = wrappedValue
}
var wrappedValue: Value {
get { fatalError() }
set { fatalError() }
}
static subscript<EnclosingSelf>(
_enclosingInstance observed: EnclosingSelf,
wrapped wrappedKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Value>,
storage storageKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Self>
) -> Value {
get { fatalError() }
set { fatalError() }
}
}
@available(macOS, unavailable)
class UnavailableOnMacOSObserved {
@Observable var observedProperty = 17
}
@available(*, unavailable)
class UniversallyUnavailableObserved {
@Observable var observedProperty = 17
}