Files
swift-mirror/test/Sema/property_wrapper_availability.swift
Allan Shortlidge eafea5b21e Sema: Relax availability checking in universally unavailable contexts.
Recent refactoring fixed a bug that previously caused `f()` to be checked as if
it were unavailable only on macOS in the following example:

```
@available(macOS, unavailable)
struct Outer {
  @available(*, unavailable)
  func f() {
    someFunctionUnavailableOnMacOS()
  }
}
```

Unfortunately, fixing that bug made a different existing availability checking
rule more problematic. References to declarations that are unavailable on the
current platform have been diagnosed as unavailable even in contexts that are
universally unavailable. This long standing behavior is overly strict but it
rarely had consequences. However, now that the example above is modeled
correctly, this overly strict behavior is causing some source compatibility
issues. The easiest solution is to relax the overly strict checking.

Resolves rdar://141124478.
2024-12-09 17:15:15 -08:00

189 lines
8.4 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 8 {{'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 // expected-error {{'wrappedValue' is only available in macOS 51 or newer}}
}
@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
@UnavailableWrapper var unavailableInferred = S()
@WrappedValueUnavailableOnMacOS var unavailableWrappedValue: S
@WrappedValueAvailable51 var wrappedValueAavailable51: S // expected-error {{'wrappedValue' is only available in macOS 51 or newer}}
}
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 // expected-error {{'wrappedValue' is only available in macOS 51 or newer}}
) {
@AlwaysAvailableWrapper var alwaysAvailableLocal = S()
@Available51Wrapper var available51Local = S()
@DeprecatedWrapper var deprecatedLocal = S()
@UnavailableWrapper var unavailableLocal = S()
@WrappedValueUnavailableOnMacOS var unavailableWrappedValueLocal = S()
@WrappedValueAvailable51 var wrappedValueAavailable51 = S() // expected-error {{'wrappedValue' is only available in macOS 51 or newer}}
}
@available(macOS, unavailable)
func unavailableOnMacOSFunc(
@AlwaysAvailableWrapper _ alwaysAvailable: S,
@Available51Wrapper _ available51: S,
@DeprecatedWrapper _ deprecated: S,
@UnavailableWrapper _ unavailable: S,
@WrappedValueUnavailableOnMacOS _ unavailableWrappedValue: S,
@WrappedValueAvailable51 _ wrappedValueAavailable51: S // expected-error {{'wrappedValue' is only available in macOS 51 or newer}}
) {
@AlwaysAvailableWrapper var alwaysAvailableLocal = S()
@Available51Wrapper var available51Local = S()
@DeprecatedWrapper var deprecatedLocal = S()
@UnavailableWrapper var unavailableLocal = S()
@WrappedValueUnavailableOnMacOS var unavailableWrappedValueLocal = S()
@WrappedValueAvailable51 var wrappedValueAavailable51 = S() // expected-error {{'wrappedValue' is only available in macOS 51 or newer}}
}