mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
196 lines
9.2 KiB
Swift
196 lines
9.2 KiB
Swift
// RUN: %target-typecheck-verify-swift \
|
|
// RUN: -enable-experimental-feature CustomAvailability \
|
|
// RUN: -define-enabled-availability-domain EnabledDomain \
|
|
// RUN: -define-disabled-availability-domain DisabledDomain \
|
|
// RUN: -define-dynamic-availability-domain DynamicDomain
|
|
|
|
// REQUIRES: swift_feature_CustomAvailability
|
|
|
|
func alwaysAvailable() { }
|
|
|
|
@available(EnabledDomain)
|
|
func availableInEnabledDomain() { }
|
|
|
|
@available(EnabledDomain, unavailable)
|
|
func unavailableInEnabledDomain() { } // expected-note * {{'unavailableInEnabledDomain()' has been explicitly marked unavailable here}}
|
|
|
|
@available(DisabledDomain, unavailable)
|
|
func unavailableInDisabledDomain() { } // expected-note * {{'unavailableInDisabledDomain()' has been explicitly marked unavailable here}}
|
|
|
|
@available(DynamicDomain)
|
|
func availableInDynamicDomain() { }
|
|
|
|
@available(DynamicDomain, deprecated, message: "Use something else")
|
|
func deprecatedInDynamicDomain() { }
|
|
|
|
@available(DynamicDomain, unavailable)
|
|
func unavailableInDynamicDomain() { } // expected-note * {{'unavailableInDynamicDomain()' has been explicitly marked unavailable here}}
|
|
|
|
@available(UnknownDomain) // expected-warning {{unrecognized platform name 'UnknownDomain'}}
|
|
func availableInUnknownDomain() { }
|
|
|
|
func testDeployment() {
|
|
alwaysAvailable()
|
|
availableInEnabledDomain() // expected-error {{'availableInEnabledDomain()' is only available in EnabledDomain}}
|
|
unavailableInEnabledDomain() // expected-error {{'unavailableInEnabledDomain()' is unavailable}}
|
|
unavailableInDisabledDomain() // expected-error {{'unavailableInDisabledDomain()' is unavailable}}
|
|
deprecatedInDynamicDomain() // expected-warning {{'deprecatedInDynamicDomain()' is deprecated: Use something else}}
|
|
unavailableInDynamicDomain() // expected-error {{'unavailableInDynamicDomain()' is unavailable}}
|
|
availableInDynamicDomain() // expected-error {{'availableInDynamicDomain()' is only available in DynamicDomain}}
|
|
availableInUnknownDomain()
|
|
}
|
|
|
|
func testIfAvailable(_ truthy: Bool) {
|
|
if #available(EnabledDomain) {
|
|
availableInEnabledDomain()
|
|
unavailableInEnabledDomain() // expected-error {{'unavailableInEnabledDomain()' is unavailable}}
|
|
availableInDynamicDomain() // expected-error {{'availableInDynamicDomain()' is only available in DynamicDomain}}
|
|
unavailableInDynamicDomain() // expected-error {{'unavailableInDynamicDomain()' is unavailable}}
|
|
|
|
if #available(DynamicDomain) {
|
|
availableInEnabledDomain()
|
|
unavailableInEnabledDomain() // expected-error {{'unavailableInEnabledDomain()' is unavailable}}
|
|
availableInDynamicDomain()
|
|
unavailableInDynamicDomain() // expected-error {{'unavailableInDynamicDomain()' is unavailable}}
|
|
} else {
|
|
availableInEnabledDomain()
|
|
unavailableInEnabledDomain() // expected-error {{'unavailableInEnabledDomain()' is unavailable}}
|
|
availableInDynamicDomain() // expected-error {{'availableInDynamicDomain()' is only available in DynamicDomain}}
|
|
unavailableInDynamicDomain()
|
|
}
|
|
|
|
if #unavailable(EnabledDomain) {
|
|
// Unreachable.
|
|
availableInEnabledDomain()
|
|
unavailableInEnabledDomain() // expected-error {{'unavailableInEnabledDomain()' is unavailable}}
|
|
availableInDynamicDomain() // expected-error {{'availableInDynamicDomain()' is only available in DynamicDomain}}
|
|
unavailableInDynamicDomain() // expected-error {{'unavailableInDynamicDomain()' is unavailable}}
|
|
}
|
|
} else {
|
|
availableInEnabledDomain() // expected-error {{'availableInEnabledDomain()' is only available in EnabledDomain}}
|
|
unavailableInEnabledDomain()
|
|
availableInDynamicDomain() // expected-error {{'availableInDynamicDomain()' is only available in DynamicDomain}}
|
|
unavailableInDynamicDomain() // expected-error {{'unavailableInDynamicDomain()' is unavailable}}
|
|
}
|
|
|
|
if #available(EnabledDomain), #available(DynamicDomain) {
|
|
availableInEnabledDomain()
|
|
unavailableInEnabledDomain() // expected-error {{'unavailableInEnabledDomain()' is unavailable}}
|
|
availableInDynamicDomain()
|
|
unavailableInDynamicDomain() // expected-error {{'unavailableInDynamicDomain()' is unavailable}}
|
|
} else {
|
|
// In this branch, we only know that one of the domains is unavailable,
|
|
// but we don't know which.
|
|
availableInEnabledDomain() // expected-error {{'availableInEnabledDomain()' is only available in EnabledDomain}}
|
|
unavailableInEnabledDomain() // expected-error {{'unavailableInEnabledDomain()' is unavailable}}
|
|
availableInDynamicDomain() // expected-error {{'availableInDynamicDomain()' is only available in DynamicDomain}}
|
|
unavailableInDynamicDomain() // expected-error {{'unavailableInDynamicDomain()' is unavailable}}
|
|
}
|
|
|
|
if #available(EnabledDomain), truthy {
|
|
availableInEnabledDomain()
|
|
unavailableInEnabledDomain() // expected-error {{'unavailableInEnabledDomain()' is unavailable}}
|
|
} else {
|
|
// In this branch, the state of EnabledDomain remains unknown since
|
|
// execution will reach here if "truthy" is false.
|
|
availableInEnabledDomain() // expected-error {{'availableInEnabledDomain()' is only available in EnabledDomain}}
|
|
unavailableInEnabledDomain() // expected-error {{'unavailableInEnabledDomain()' is unavailable}}
|
|
}
|
|
|
|
if #unavailable(EnabledDomain) {
|
|
availableInEnabledDomain() // expected-error {{'availableInEnabledDomain()' is only available in EnabledDomain}}
|
|
unavailableInEnabledDomain()
|
|
} else {
|
|
availableInEnabledDomain()
|
|
unavailableInEnabledDomain() // expected-error {{'unavailableInEnabledDomain()' is unavailable}}
|
|
}
|
|
|
|
// FIXME: [availability] Support mixed #available and #unavailable.
|
|
if #unavailable(EnabledDomain), #available(DynamicDomain) {
|
|
// expected-error@-1 {{#available and #unavailable cannot be in the same statement}}
|
|
}
|
|
}
|
|
|
|
func testWhileAvailable() {
|
|
while #available(EnabledDomain) {
|
|
availableInEnabledDomain()
|
|
unavailableInEnabledDomain() // expected-error {{'unavailableInEnabledDomain()' is unavailable}}
|
|
}
|
|
|
|
while #unavailable(EnabledDomain) {
|
|
availableInEnabledDomain() // expected-error {{'availableInEnabledDomain()' is only available in EnabledDomain}}
|
|
unavailableInEnabledDomain()
|
|
}
|
|
}
|
|
|
|
func testGuardAvailable() {
|
|
guard #available(EnabledDomain) else {
|
|
availableInEnabledDomain() // expected-error {{'availableInEnabledDomain()' is only available in EnabledDomain}}
|
|
unavailableInEnabledDomain()
|
|
availableInDynamicDomain() // expected-error {{'availableInDynamicDomain()' is only available in DynamicDomain}}
|
|
|
|
return
|
|
}
|
|
|
|
availableInEnabledDomain()
|
|
unavailableInEnabledDomain() // expected-error {{'unavailableInEnabledDomain()' is unavailable}}
|
|
availableInDynamicDomain() // expected-error {{'availableInDynamicDomain()' is only available in DynamicDomain}}
|
|
}
|
|
|
|
@available(EnabledDomain)
|
|
func testEnabledDomainAvailable() {
|
|
availableInEnabledDomain()
|
|
unavailableInEnabledDomain() // expected-error {{'unavailableInEnabledDomain()' is unavailable}}
|
|
|
|
if #available(EnabledDomain) {} // FIXME: [availability] Diagnose as redundant
|
|
if #unavailable(EnabledDomain) {} // FIXME: [availability] Diagnose as unreachable
|
|
|
|
alwaysAvailable()
|
|
unavailableInDisabledDomain() // expected-error {{'unavailableInDisabledDomain()' is unavailable}}
|
|
deprecatedInDynamicDomain() // expected-warning {{'deprecatedInDynamicDomain()' is deprecated: Use something else}}
|
|
availableInDynamicDomain() // expected-error {{'availableInDynamicDomain()' is only available in DynamicDomain}}
|
|
availableInUnknownDomain()
|
|
}
|
|
|
|
@available(EnabledDomain, unavailable)
|
|
func testEnabledDomainUnavailable() {
|
|
availableInEnabledDomain() // expected-error {{'availableInEnabledDomain()' is only available in EnabledDomain}}
|
|
unavailableInEnabledDomain()
|
|
|
|
if #available(EnabledDomain) {} // FIXME: [availability] Diagnose as unreachable
|
|
if #unavailable(EnabledDomain) {} // FIXME: [availability] Diagnose as redundant
|
|
|
|
alwaysAvailable()
|
|
unavailableInDisabledDomain() // expected-error {{'unavailableInDisabledDomain()' is unavailable}}
|
|
deprecatedInDynamicDomain() // expected-warning {{'deprecatedInDynamicDomain()' is deprecated: Use something else}}
|
|
availableInDynamicDomain() // expected-error {{'availableInDynamicDomain()' is only available in DynamicDomain}}
|
|
availableInUnknownDomain()
|
|
}
|
|
|
|
@available(*, unavailable)
|
|
func testUniversallyUnavailable() {
|
|
alwaysAvailable()
|
|
// FIXME: [availability] Diagnostic consistency: potentially unavailable declaration shouldn't be diagnosed
|
|
// in contexts that are unavailable to broader domains
|
|
availableInEnabledDomain() // expected-error {{'availableInEnabledDomain()' is only available in EnabledDomain}}
|
|
unavailableInDisabledDomain()
|
|
deprecatedInDynamicDomain() // expected-warning {{'deprecatedInDynamicDomain()' is deprecated: Use something else}}
|
|
availableInDynamicDomain() // expected-error {{'availableInDynamicDomain()' is only available in DynamicDomain}}
|
|
availableInUnknownDomain()
|
|
|
|
if #available(EnabledDomain) {} // FIXME: [availability] Diagnose?
|
|
if #unavailable(EnabledDomain) {} // FIXME: [availability] Diagnose?
|
|
}
|
|
|
|
@available(EnabledDomain)
|
|
struct EnabledDomainAvailable {
|
|
@available(DynamicDomain)
|
|
func dynamicDomainAvailableMethod() {
|
|
availableInEnabledDomain()
|
|
availableInDynamicDomain()
|
|
|
|
alwaysAvailable()
|
|
unavailableInDisabledDomain() // expected-error {{'unavailableInDisabledDomain()' is unavailable}}
|
|
}
|
|
}
|