diff --git a/CHANGELOG.md b/CHANGELOG.md index d2bb92dd34743..3ee272369c877 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,33 @@ ## Swift 6.2 +* The Swift compiler no longer diagnoses references to declarations that are + potentially unavailable because the platform version might not be new enough + when those references occur inside of contexts that are also unavailable to + that platform. This addresses a long-standing nuisance for multi-platform + code. However, there is also a chance that existing source code may become + ambiguous as a result: + + ```swift + struct A {} + struct B {} + + func potentiallyAmbiguous(_: A) {} + + @available(macOS 99, *) + func potentiallyAmbiguous(_: B) {} + + @available(macOS, unavailable) + func unavailableOnMacOS() { + potentiallyAmbiguous(.init()) // error: ambiguous use of 'init()' + } + ``` + + Code that is now ambiguous as a result should likely be restructured since + disambiguation based on platform introduction alone has never been a reliable + strategy, given that the code would eventually become ambiguous anyways when + the deployment target is raised. + * [SE-0419][]: Introduced the new `Runtime` module, which contains a public API that can generate backtraces, presently supported on macOS and Linux. Capturing a diff --git a/lib/AST/AvailabilityConstraint.cpp b/lib/AST/AvailabilityConstraint.cpp index 9968cdcf2d34a..5377057ad94ec 100644 --- a/lib/AST/AvailabilityConstraint.cpp +++ b/lib/AST/AvailabilityConstraint.cpp @@ -113,25 +113,59 @@ DeclAvailabilityConstraints::getPrimaryConstraint() const { return result; } +static bool canIgnoreConstraintInUnavailableContexts( + const Decl *decl, const AvailabilityConstraint &constraint) { + auto domain = constraint.getDomain(); + + switch (constraint.getReason()) { + case AvailabilityConstraint::Reason::UnconditionallyUnavailable: + // Always reject uses of universally unavailable declarations, regardless + // of context, since there are no possible compilation configurations in + // which they are available. However, make an exception for types and + // conformances, which can sometimes be awkward to avoid references to. + if (!isa(decl) && !isa(decl)) { + if (domain.isUniversal() || domain.isSwiftLanguage()) + return false; + } + return true; + + case AvailabilityConstraint::Reason::PotentiallyUnavailable: + switch (domain.getKind()) { + case AvailabilityDomain::Kind::Universal: + case AvailabilityDomain::Kind::SwiftLanguage: + case AvailabilityDomain::Kind::PackageDescription: + case AvailabilityDomain::Kind::Embedded: + case AvailabilityDomain::Kind::Custom: + return false; + case AvailabilityDomain::Kind::Platform: + // Platform availability only applies to the target triple that the + // binary is being compiled for. Since the same declaration can be + // potentially unavailable from a given context when compiling for one + // platform, but available from that context when compiling for a + // different platform, it is overly strict to enforce potential platform + // unavailability constraints in contexts that are unavailable to that + // platform. + return true; + } + return constraint.getDomain().isPlatform(); + + case AvailabilityConstraint::Reason::Obsoleted: + case AvailabilityConstraint::Reason::UnavailableForDeployment: + return false; + } +} + static bool -isInsideCompatibleUnavailableDeclaration(const Decl *decl, - const SemanticAvailableAttr &attr, - const AvailabilityContext &context) { +shouldIgnoreConstraintInContext(const Decl *decl, + const AvailabilityConstraint &constraint, + const AvailabilityContext &context) { if (!context.isUnavailable()) return false; - if (!attr.isUnconditionallyUnavailable()) + if (!canIgnoreConstraintInUnavailableContexts(decl, constraint)) return false; - // Refuse calling universally unavailable functions from unavailable code, - // but allow the use of types. - auto domain = attr.getDomain(); - if (!isa(decl) && !isa(decl)) { - if (domain.isUniversal() || domain.isSwiftLanguage()) - return false; - } - - return context.containsUnavailableDomain(domain); + return context.containsUnavailableDomain(constraint.getDomain()); } /// Returns the `AvailabilityConstraint` that describes how \p attr restricts @@ -218,8 +252,7 @@ static void getAvailabilityConstraintsForDecl( // declaration is unconditionally unavailable in a domain for which // the context is already unavailable. llvm::erase_if(constraints, [&](const AvailabilityConstraint &constraint) { - return isInsideCompatibleUnavailableDeclaration(decl, constraint.getAttr(), - context); + return shouldIgnoreConstraintInContext(decl, constraint, context); }); } diff --git a/test/Constraints/availability_macos.swift b/test/Constraints/availability_macos.swift new file mode 100644 index 0000000000000..06e326424ec62 --- /dev/null +++ b/test/Constraints/availability_macos.swift @@ -0,0 +1,37 @@ +// RUN: %target-typecheck-verify-swift + +// REQUIRES: OS=macosx + +struct A {} // expected-note * {{found this candidate}} +struct B {} // expected-note * {{found this candidate}} + +func ambiguousInFarFuture(_: A) {} + +@available(macOS 99, *) +func ambiguousInFarFuture(_: B) {} + +struct S { + func ambiguousInFarFuture(_: A) {} +} + +@available(macOS 99, *) +extension S { + func ambiguousInFarFuture(_: B) {} +} + +func testDeploymentTarget(_ s: S) { + ambiguousInFarFuture(.init()) + s.ambiguousInFarFuture(.init()) +} + +@available(macOS 99, *) +func testFarFuture(_ s: S) { + ambiguousInFarFuture(.init()) // expected-error {{ambiguous use of 'init()'}} + s.ambiguousInFarFuture(.init()) // expected-error {{ambiguous use of 'init()'}} +} + +@available(macOS, unavailable) +func testUnavailable(_ s: S) { + ambiguousInFarFuture(.init()) // expected-error {{ambiguous use of 'init()'}} + s.ambiguousInFarFuture(.init()) // expected-error {{ambiguous use of 'init()'}} +} diff --git a/test/Sema/availability_scopes.swift b/test/Sema/availability_scopes.swift index b3a3ea56964c1..8042beeb145b2 100644 --- a/test/Sema/availability_scopes.swift +++ b/test/Sema/availability_scopes.swift @@ -253,19 +253,19 @@ extension SomeClass { // CHECK-NEXT: {{^}} (decl_implicit version=50 decl=extension.SomeClass // CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=extension.SomeClass -// CHECK-NEXT: {{^}} (decl version=51 unavailable=macOS decl=functionWithStmtConditionsInUnavailableExt() +// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=functionWithStmtConditionsInUnavailableExt() // CHECK-NEXT: {{^}} (condition_following_availability version=52 unavailable=macOS // CHECK-NEXT: {{^}} (condition_following_availability version=53 unavailable=macOS // CHECK-NEXT: {{^}} (if_then version=53 unavailable=macOS // CHECK-NEXT: {{^}} (condition_following_availability version=54 unavailable=macOS // CHECK-NEXT: {{^}} (if_then version=54 unavailable=macOS // CHECK-NEXT: {{^}} (condition_following_availability version=55 unavailable=macOS -// CHECK-NEXT: {{^}} (decl version=55 unavailable=macOS decl=funcInGuardElse() +// CHECK-NEXT: {{^}} (decl version=54 unavailable=macOS decl=funcInGuardElse() // CHECK-NEXT: {{^}} (guard_fallthrough version=55 unavailable=macOS // CHECK-NEXT: {{^}} (condition_following_availability version=56 unavailable=macOS // CHECK-NEXT: {{^}} (guard_fallthrough version=56 unavailable=macOS -// CHECK-NEXT: {{^}} (decl version=57 unavailable=macOS decl=funcInInnerIfElse() -// CHECK-NEXT: {{^}} (decl version=53 unavailable=macOS decl=funcInOuterIfElse() +// CHECK-NEXT: {{^}} (decl version=53 unavailable=macOS decl=funcInInnerIfElse() +// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=funcInOuterIfElse() @available(OSX, unavailable) extension SomeClass { @available(OSX 51, *) @@ -401,7 +401,7 @@ extension SomeEnum { // CHECK-NEXT: {{^}} (decl_implicit version=50 decl=extension.SomeEnum // CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=extension.SomeEnum // CHECK-NEXT: {{^}} (decl_implicit version=50 unavailable=macOS decl=availableMacOS_52 -// CHECK-NEXT: {{^}} (decl version=52 unavailable=macOS decl=availableMacOS_52 +// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=availableMacOS_52 // CHECK-NEXT: {{^}} (decl version=50 unavailable=* decl=neverAvailable() @available(macOS, unavailable) @@ -418,10 +418,25 @@ extension SomeEnum { // CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=unavailableOnMacOSAndIntroduced() -@available(macOS, unavailable, introduced: 52) +@available(macOS, unavailable) +@available(macOS, introduced: 52) func unavailableOnMacOSAndIntroduced() { } +// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=introducedOnMacOSAndUnavailable() + +@available(macOS, introduced: 53) +@available(macOS, unavailable) +func introducedOnMacOSAndUnavailable() { +} + + +// CHECK-NEXT: {{^}} (decl version=50 unavailable=macOS decl=unavailableOnMacOSAndIntroducedSameAttr() + +@available(macOS, unavailable, introduced: 54) +func unavailableOnMacOSAndIntroducedSameAttr() { +} + // CHECK-NEXT: {{^}} (decl version=50 unavailable=* decl=NeverAvailable // CHECK-NEXT: {{^}} (decl version=50 unavailable=* decl=unavailableOnMacOS() diff --git a/test/Sema/property_wrapper_availability.swift b/test/Sema/property_wrapper_availability.swift index daf3ab2771322..030be36469e15 100644 --- a/test/Sema/property_wrapper_availability.swift +++ b/test/Sema/property_wrapper_availability.swift @@ -99,7 +99,7 @@ struct UnavailableStruct { @UnavailableWrapper var unavailableInferred = S() @WrappedValueUnavailableOnMacOS var unavailableWrappedValue: S - @WrappedValueAvailable51 var wrappedValueAavailable51: S // expected-error {{'wrappedValue' is only available in macOS 51 or newer}} + @WrappedValueAvailable51 var wrappedValueAavailable51: S } @available(macOS, unavailable) @@ -117,7 +117,7 @@ struct UnavailableOnMacOSStruct { @UnavailableWrapper var unavailableInferred = S() @WrappedValueUnavailableOnMacOS var unavailableWrappedValue: S - @WrappedValueAvailable51 var wrappedValueAavailable51: S // expected-error {{'wrappedValue' is only available in macOS 51 or newer}} + @WrappedValueAvailable51 var wrappedValueAavailable51: S } func alwaysAvailableFunc( // expected-note 4 {{add @available attribute to enclosing global function}} @@ -160,14 +160,14 @@ func unavailableFunc( @DeprecatedWrapper _ deprecated: S, @UnavailableWrapper _ unavailable: S, @WrappedValueUnavailableOnMacOS _ unavailableWrappedValue: S, - @WrappedValueAvailable51 _ wrappedValueAavailable51: S // expected-error {{'wrappedValue' is only available in macOS 51 or newer}} + @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() // expected-error {{'wrappedValue' is only available in macOS 51 or newer}} + @WrappedValueAvailable51 var wrappedValueAavailable51 = S() } @available(macOS, unavailable) @@ -177,12 +177,12 @@ func unavailableOnMacOSFunc( @DeprecatedWrapper _ deprecated: S, @UnavailableWrapper _ unavailable: S, @WrappedValueUnavailableOnMacOS _ unavailableWrappedValue: S, - @WrappedValueAvailable51 _ wrappedValueAavailable51: S // expected-error {{'wrappedValue' is only available in macOS 51 or newer}} + @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() // expected-error {{'wrappedValue' is only available in macOS 51 or newer}} + @WrappedValueAvailable51 var wrappedValueAavailable51 = S() } diff --git a/test/attr/attr_availability_transitive_osx.swift b/test/attr/attr_availability_transitive_osx.swift index b0a17ee2f3b93..7187ca6c26ea0 100644 --- a/test/attr/attr_availability_transitive_osx.swift +++ b/test/attr/attr_availability_transitive_osx.swift @@ -87,8 +87,7 @@ func never_available_func( ) { always() never() // expected-error {{'never()' is unavailable}} - osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + osx_future() osx() osx_ios() osx_extension() @@ -105,8 +104,7 @@ func osx_func( ) { always() never() // expected-error {{'never()' is unavailable}} - osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + osx_future() osx() osx_ios() osx_extension() @@ -159,7 +157,7 @@ var never_var: ( ) = ( always(), never(), // expected-error {{'never()' is unavailable}} - osx_future(), // expected-error {{'osx_future()' is only available in macOS 99 or newer}} + osx_future(), osx(), osx_ios(), osx_extension() @@ -176,7 +174,7 @@ var osx_var: ( ) = ( always(), never(), // expected-error {{'never()' is unavailable}} - osx_future(), // expected-error {{'osx_future()' is only available in macOS 99 or newer}} + osx_future(), osx(), osx_ios(), osx_extension() @@ -218,7 +216,7 @@ struct AlwaysAvailableContainer { // expected-note 2 {{add @available attribute struct NeverAvailableContainer { // expected-note 2 {{'NeverAvailableContainer' has been explicitly marked unavailable here}} let always_var: AlwaysAvailable = always() let never_var: NeverAvailable = never() // expected-error {{'never()' is unavailable}} - let osx_future_var: OSXFutureAvailable = osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} + let osx_future_var: OSXFutureAvailable = osx_future() let osx_var: OSXUnavailable = osx() let osx_ios_var: MultiPlatformUnavailable = osx_ios() let osx_extension_var: OSXAppExtensionsUnavailable = osx_extension() @@ -228,7 +226,7 @@ struct NeverAvailableContainer { // expected-note 2 {{'NeverAvailableContainer' struct OSXUnavailableContainer { // expected-note 2 {{'OSXUnavailableContainer' has been explicitly marked unavailable here}} let always_var: AlwaysAvailable = always() let never_var: NeverAvailable = never() // expected-error {{'never()' is unavailable}} - let osx_future_var: OSXFutureAvailable = osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} + let osx_future_var: OSXFutureAvailable = osx_future() let osx_var: OSXUnavailable = osx() let osx_ios_var: MultiPlatformUnavailable = osx_ios() let osx_extension_var: OSXAppExtensionsUnavailable = osx_extension() @@ -301,8 +299,7 @@ extension ExtendMe { ) { always() never() // expected-error {{'never()' is unavailable}} - osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + osx_future() osx() osx_ios() osx_extension() @@ -319,8 +316,7 @@ extension ExtendMe { ) { always() never() // expected-error {{'never()' is unavailable}} - osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + osx_future() osx() osx_ios() osx_extension() @@ -337,15 +333,14 @@ extension ExtendMe { ) { always() never() // expected-error {{'never()' is unavailable}} - osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + osx_future() osx() osx_ios() osx_extension() } @available(OSXApplicationExtension, unavailable) - func never_available_extension_osx_app_extension_method( // expected-note {{add @available attribute to enclosing instance method}} + func never_available_extension_osx_app_extension_method( _: AlwaysAvailable, _: NeverAvailable, _: OSXFutureAvailable, @@ -355,8 +350,7 @@ extension ExtendMe { ) { always() never() // expected-error {{'never()' is unavailable}} - osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + osx_future() osx() osx_ios() osx_extension() @@ -380,8 +374,7 @@ extension ExtendMe { ) { always() never() // expected-error {{'never()' is unavailable}} - osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + osx_future() osx() osx_ios() osx_extension() @@ -398,8 +391,7 @@ extension ExtendMe { ) { always() never() // expected-error {{'never()' is unavailable}} - osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + osx_future() osx() osx_ios() osx_extension() @@ -416,15 +408,14 @@ extension ExtendMe { ) { always() never() // expected-error {{'never()' is unavailable}} - osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + osx_future() osx() osx_ios() osx_extension() } @available(OSXApplicationExtension, unavailable) - func osx_extension_osx_app_extension_method( // expected-note {{add @available attribute to enclosing instance method}} + func osx_extension_osx_app_extension_method( _: AlwaysAvailable, _: NeverAvailable, _: OSXFutureAvailable, @@ -434,8 +425,7 @@ extension ExtendMe { ) { always() never() // expected-error {{'never()' is unavailable}} - osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + osx_future() osx() osx_ios() osx_extension() @@ -477,8 +467,7 @@ extension ExtendMe { // expected-note * {{add @available attribute to enclosing ) { always() never() // expected-error {{'never()' is unavailable}} - osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + osx_future() osx() osx_ios() osx_extension() @@ -495,8 +484,7 @@ extension ExtendMe { // expected-note * {{add @available attribute to enclosing ) { always() never() // expected-error {{'never()' is unavailable}} - osx_future() // expected-error {{'osx_future()' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + osx_future() osx() osx_ios() osx_extension() @@ -534,7 +522,7 @@ func available_func_call_extension_methods(_ e: ExtendMe) { // expected-note {{a } @available(OSX, obsoleted: 10.9) -struct OSXObsoleted {} // expected-note 2 {{'OSXObsoleted' was obsoleted in macOS 10.9}} +struct OSXObsoleted {} // expected-note 4 {{'OSXObsoleted' was obsoleted in macOS 10.9}} @available(OSX, unavailable) @available(OSX, introduced: 99) @@ -561,17 +549,46 @@ func osx_unavailable_func( OSXUnavailableAndIntroducedInFutureSameAttribute, OSXIntroducedInFutureAndUnavailable ) { - // FIXME: [availability] Stop diagnosing potential unavailability or obsoletion in an unavailable context. - _ = OSXFutureAvailable() // expected-error {{'OSXFutureAvailable' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + // FIXME: [availability] Stop diagnosing obsoletion in an unavailable context. + _ = OSXFutureAvailable() _ = OSXObsoleted() // expected-error {{'OSXObsoleted' is unavailable in macOS}} _ = OSXUnavailableAndIntroducedInFuture() _ = OSXUnavailableAndIntroducedInFutureSameAttribute() _ = OSXIntroducedInFutureAndUnavailable() func takesType(_ t: T.Type) {} - takesType(OSXFutureAvailable.self) // expected-error {{'OSXFutureAvailable' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + takesType(OSXFutureAvailable.self) + takesType(OSXObsoleted.self) // expected-error {{'OSXObsoleted' is unavailable in macOS}} + takesType(OSXUnavailableAndIntroducedInFuture.self) + takesType(OSXUnavailableAndIntroducedInFutureSameAttribute.self) + takesType(OSXIntroducedInFutureAndUnavailable.self) + + return (s1, s2, s3, s4, s5) +} + +@available(OSX, unavailable, introduced: 99) +func osx_unavailable_and_introduced_func( + _ s1: OSXFutureAvailable, + _ s2: OSXObsoleted, + _ s3: OSXUnavailableAndIntroducedInFuture, + _ s4: OSXUnavailableAndIntroducedInFutureSameAttribute, + _ s5: OSXIntroducedInFutureAndUnavailable, +) -> ( + OSXFutureAvailable, + OSXObsoleted, + OSXUnavailableAndIntroducedInFuture, + OSXUnavailableAndIntroducedInFutureSameAttribute, + OSXIntroducedInFutureAndUnavailable +) { + // FIXME: [availability] Stop diagnosing obsoletion in an unavailable context. + _ = OSXFutureAvailable() + _ = OSXObsoleted() // expected-error {{'OSXObsoleted' is unavailable in macOS}} + _ = OSXUnavailableAndIntroducedInFuture() + _ = OSXUnavailableAndIntroducedInFutureSameAttribute() + _ = OSXIntroducedInFutureAndUnavailable() + + func takesType(_ t: T.Type) {} + takesType(OSXFutureAvailable.self) takesType(OSXObsoleted.self) // expected-error {{'OSXObsoleted' is unavailable in macOS}} takesType(OSXUnavailableAndIntroducedInFuture.self) takesType(OSXUnavailableAndIntroducedInFutureSameAttribute.self) diff --git a/test/attr/attr_availability_transitive_osx_appext.swift b/test/attr/attr_availability_transitive_osx_appext.swift index 412af439ffe15..371b90cbd5943 100644 --- a/test/attr/attr_availability_transitive_osx_appext.swift +++ b/test/attr/attr_availability_transitive_osx_appext.swift @@ -386,8 +386,7 @@ func osx_func_call_extension_methods(_ e: ExtendMe) { e.never_available_extension_osx_future_method() // expected-error {{'never_available_extension_osx_future_method()' is unavailable}} e.osx_extension_osx_future_method() - e.osx_app_extension_extension_osx_future_method() // expected-error {{'osx_app_extension_extension_osx_future_method()' is only available in macOS 99 or newer}} - // expected-note@-1 {{add 'if #available' version check}} + e.osx_app_extension_extension_osx_future_method() e.osx_app_extension_extension_never_available_method() // expected-error {{'osx_app_extension_extension_never_available_method()' is unavailable}} e.osx_app_extension_extension_osx_method() e.osx_app_extension_extension_osx_app_extension_method() diff --git a/test/attr/attr_inlinable_available.swift b/test/attr/attr_inlinable_available.swift index 1f948801dc06f..4b6cd0e875a75 100644 --- a/test/attr/attr_inlinable_available.swift +++ b/test/attr/attr_inlinable_available.swift @@ -321,14 +321,14 @@ public func alwaysUnavailable( ) { defer { _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}} + _ = AfterDeploymentTarget() } _ = NoAvailable() _ = BeforeInliningTarget() _ = AtInliningTarget() _ = BetweenTargets() _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}} + _ = AfterDeploymentTarget() _ = Unavailable() if #available(macOS 11, *) { @@ -568,14 +568,14 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add @available attri ) { defer { _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}} + _ = AfterDeploymentTarget() } _ = NoAvailable() _ = BeforeInliningTarget() _ = AtInliningTarget() _ = BetweenTargets() _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}} + _ = AfterDeploymentTarget() _ = Unavailable() if #available(macOS 11, *) { @@ -718,7 +718,7 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add @available attri _ = AtInliningTarget() _ = BetweenTargets() _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}} + _ = AfterDeploymentTarget() if #available(macOS 11, *) { _ = AfterDeploymentTarget() @@ -727,7 +727,7 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add @available attri return () } -@inlinable public var inlinedNoAvailableGlobalUnavailableSetter: Any { // expected-note {{add @available attribute to enclosing var}} +@inlinable public var inlinedNoAvailableGlobalUnavailableSetter: Any { get { fatalError() } @@ -738,7 +738,7 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add @available attri _ = AtInliningTarget() _ = BetweenTargets() _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}} + _ = AfterDeploymentTarget() if #available(macOS 11, *) { _ = AfterDeploymentTarget() @@ -847,7 +847,7 @@ public func defaultArgsUseUnavailable( _: Any = AtInliningTarget.self, _: Any = BetweenTargets.self, _: Any = AtDeploymentTarget.self, - _: Any = AfterDeploymentTarget.self, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} + _: Any = AfterDeploymentTarget.self, _: Any = Unavailable.self ) {} @@ -909,7 +909,7 @@ public struct PropertyWrapper { public init(_ value: T) { self.wrappedValue = value } } -public struct PublicStruct { // expected-note 21 {{add @available attribute}} +public struct PublicStruct { // expected-note 20 {{add @available attribute}} // Public property declarations are exposed. public var aPublic: NoAvailable, bPublic: BeforeInliningTarget, @@ -961,7 +961,7 @@ public struct PublicStruct { // expected-note 21 {{add @available attribute}} @available(macOS, unavailable) public var fUnavailable: AfterDeploymentTarget { - AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available' version check}} + AfterDeploymentTarget() } // The inferred types of public properties are exposed. @@ -1167,7 +1167,7 @@ public struct UnavailablePublicStruct { cPublicInit: Any = AtInliningTarget(), dPublicInit: Any = BetweenTargets(), ePublicInit: Any = AtDeploymentTarget(), - fPublicInit: Any = AfterDeploymentTarget(), // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} + fPublicInit: Any = AfterDeploymentTarget(), gPublicInit: Any = Unavailable() var aInternal: NoAvailable = .init(),