diff --git a/lib/Sema/TypeCheckAvailability.cpp b/lib/Sema/TypeCheckAvailability.cpp index 271c86c22f52b..c25dcb1c5bb90 100644 --- a/lib/Sema/TypeCheckAvailability.cpp +++ b/lib/Sema/TypeCheckAvailability.cpp @@ -78,6 +78,33 @@ bool swift::isExported(const ValueDecl *VD) { return false; } +bool swift::isExported(const ExtensionDecl *ED) { + // An extension can only be exported if it extends an exported type. + if (auto *NTD = ED->getExtendedNominal()) { + if (!isExported(NTD)) + return false; + } + + // If there are any exported members then the extension is exported. + for (const Decl *D : ED->getMembers()) { + if (isExported(D)) + return true; + } + + // If the extension declares a conformance to a public protocol then the + // extension is exported. + auto protocols = ED->getLocalProtocols(ConformanceLookupKind::OnlyExplicit); + for (const ProtocolDecl *PD : protocols) { + AccessScope scope = + PD->getFormalAccessScope(/*useDC*/nullptr, + /*treatUsableFromInlineAsPublic*/true); + if (scope.isPublic()) + return true; + } + + return false; +} + bool swift::isExported(const Decl *D) { if (auto *VD = dyn_cast(D)) { return isExported(VD); @@ -91,10 +118,7 @@ bool swift::isExported(const Decl *D) { return false; } if (auto *ED = dyn_cast(D)) { - if (auto *NTD = ED->getExtendedNominal()) - return isExported(NTD); - - return false; + return isExported(ED); } return true; diff --git a/lib/Sema/TypeCheckAvailability.h b/lib/Sema/TypeCheckAvailability.h index 1a4557a1b4a4a..08ce0db80312d 100644 --- a/lib/Sema/TypeCheckAvailability.h +++ b/lib/Sema/TypeCheckAvailability.h @@ -183,9 +183,10 @@ class ExportContext { Optional getExportabilityReason() const; }; -/// Check if a public declaration is part of a module's API; that is, this -/// will return false if the declaration is @_spi or @_implementationOnly. +/// Check if a declaration is exported as part of a module's external interface. +/// This includes public and @usableFromInline decls. bool isExported(const ValueDecl *VD); +bool isExported(const ExtensionDecl *ED); bool isExported(const Decl *D); /// Diagnose uses of unavailable declarations in expressions. diff --git a/test/Sema/availability_refinement_contexts_target_min_inlining.swift b/test/Sema/availability_refinement_contexts_target_min_inlining.swift new file mode 100644 index 0000000000000..8c189747d349f --- /dev/null +++ b/test/Sema/availability_refinement_contexts_target_min_inlining.swift @@ -0,0 +1,18 @@ +// RUN: %target-swift-frontend -swift-version 5 -enable-library-evolution -target %target-next-stable-abi-triple -typecheck -dump-type-refinement-contexts -target-min-inlining-version min %s > %t.dump 2>&1 +// RUN: %FileCheck --strict-whitespace --check-prefix CHECK-%target-os %s < %t.dump + +// REQUIRES: swift_stable_abi + +// Verify that -target-min-inlining-version min implies the correct OS version +// for the target OS. + +// CHECK-macosx: {{^}}(root versions=[10.10.0,+Inf) +// CHECK-ios: {{^}}(root versions=[8.0,+Inf) +// CHECK-tvos: {{^}}(root versions=[9.0,+Inf) +// CHECK-watchos: {{^}}(root versions=[2.0,+Inf) + +// CHECK-macosx-NEXT: {{^}} (resilience_boundary versions=[10.15.0,+Inf) decl=foo() +// CHECK-ios-NEXT: {{^}} (resilience_boundary versions=[13.0.0,+Inf) decl=foo() +// CHECK-tvos-NEXT: {{^}} (resilience_boundary versions=[13.0.0,+Inf) decl=foo() +// CHECK-watchos-NEXT: {{^}} (resilience_boundary versions=[6.0.0,+Inf) decl=foo() +func foo() {} diff --git a/test/Sema/availability_refinement_contexts_target_min_inlining_maccatalyst.swift b/test/Sema/availability_refinement_contexts_target_min_inlining_maccatalyst.swift new file mode 100644 index 0000000000000..b46b00d115d51 --- /dev/null +++ b/test/Sema/availability_refinement_contexts_target_min_inlining_maccatalyst.swift @@ -0,0 +1,15 @@ +// This test is the same as availability_refinement_contexts_target_min_inlining.swift +// but with a different run invocation to specifically test macCatalyst because +// currently there are no bots that run the tests with macCatalyst as the +// target OS. + +// RUN: %target-swift-frontend -swift-version 5 -enable-library-evolution -target %target-cpu-apple-ios14.4-macabi -typecheck -dump-type-refinement-contexts -target-min-inlining-version min %s > %t.dump 2>&1 +// RUN: %FileCheck --strict-whitespace %s < %t.dump + +// REQUIRES: maccatalyst_support + +// Verify that -target-min-inlining-version min implies 13.1 on macCatalyst. + +// CHECK: {{^}}(root versions=[13.1,+Inf) +// CHECK-NEXT: {{^}} (resilience_boundary versions=[14.4.0,+Inf) decl=foo() +func foo() {} diff --git a/test/attr/attr_inlinable_available.swift b/test/attr/attr_inlinable_available.swift index 67d9adcf48fbd..abe3ffe7a650a 100644 --- a/test/attr/attr_inlinable_available.swift +++ b/test/attr/attr_inlinable_available.swift @@ -71,11 +71,42 @@ public struct AfterDeploymentTarget { @usableFromInline internal init() {} } +// MARK: - Internal functions +// +// Both the signature and the body of internal functions should be typechecked +// using the minimum deployment target. +// + +internal func internalFn( // expected-note 3 {{add @available attribute to enclosing global function}} + _: NoAvailable, + _: BeforeInliningTarget, + _: AtInliningTarget, + _: BetweenTargets, + _: AtDeploymentTarget, + _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} +) { + defer { + _ = AtDeploymentTarget() + _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} + } + _ = NoAvailable() + _ = BeforeInliningTarget() + _ = AtInliningTarget() + _ = BetweenTargets() + _ = AtDeploymentTarget() + _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} + + if #available(macOS 11, iOS 14, tvOS 14, watchOS 7, *) { + _ = AfterDeploymentTarget() + } +} + +// MARK: - Resilient functions // -// Uses in resilient functions are based on the minimum deployment target -// (i.e. the -target). +// The body of a resilient function is typechecked using the minimum deployment +// but the function's signature should be checked with the inlining target. // public func deployedUseNoAvailable( // expected-note 5 {{add @available attribute}} @@ -224,9 +255,11 @@ public func deployedUseAfterDeploymentTarget( } +// MARK: - @inlinable functions // -// Uses in inlinable functions are based on the minimum inlining target +// Both the bodies and signatures of inlinable functions need to be typechecked +// using the minimum inlining target. // @inlinable public func inlinedUseNoAvailable( // expected-note 8 {{add @available attribute}} @@ -395,15 +428,8 @@ public func deployedUseAfterDeploymentTarget( _ = AfterDeploymentTarget() } -// -// Edge cases. -// - -// Internal functions should use the minimum deployment target. -internal func fn() { - _ = AtDeploymentTarget() -} +// MARK: - @_alwaysEmitIntoClient functions // @_alwaysEmitIntoClient acts like @inlinable. @@ -437,6 +463,9 @@ internal func fn() { } } + +// MARK: - @_backDeploy functions + // @_backDeploy acts like @inlinable. @available(macOS 10.10, iOS 8.0, tvOS 9.0, watchOS 2.0, *) @@ -471,6 +500,9 @@ public func backDeployedToInliningTarget( } } + +// MARK: - Default arguments + // Default arguments act like @inlinable. public func defaultArgsUseNoAvailable( // expected-note 3 {{add @available attribute}} @@ -551,6 +583,116 @@ internal struct InternalStruct { // expected-note {{add @available attribute}} var fInternal: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} } + +// MARK: - Extensions + +// +// Extensions are externally visible if they extend a public type and (1) have +// public members or (2) declare a conformance to a public protocol. Externally +// visible extensions should be typechecked with the inlining target. +// + +// OK, NoAvailable is always available, both internally and externally. +extension NoAvailable {} +extension NoAvailable { + public func publicFunc1() {} +} + +// OK, no public members and BetweenTargets is always available internally. +extension BetweenTargets {} + +// OK, no public members and BetweenTargets is always available internally. +extension BetweenTargets { + internal func internalFunc1() {} + private func privateFunc1() {} + fileprivate func fileprivateFunc1() {} +} + +// expected-error@+1 {{'BetweenTargets' is only available in}} expected-note@+1 {{add @available attribute to enclosing extension}} +extension BetweenTargets { + public func publicFunc1() {} +} + +// expected-error@+1 {{'BetweenTargets' is only available in}} expected-note@+1 {{add @available attribute to enclosing extension}} +extension BetweenTargets { + @usableFromInline + internal func usableFromInlineFunc1() {} +} + +// expected-error@+1 {{'BetweenTargets' is only available in}} expected-note@+1 {{add @available attribute to enclosing extension}} +extension BetweenTargets { + internal func internalFunc2() {} + private func privateFunc2() {} + fileprivate func fileprivateFunc2() {} + public func publicFunc2() {} +} + +// Same availability as BetweenTargets but internal instead of public. +@available(macOS 10.14.5, iOS 12.3, tvOS 12.3, watchOS 5.3, *) +internal struct BetweenTargetsInternal {} + +// OK, extensions on internal types are never visible externally. +extension BetweenTargetsInternal {} +extension BetweenTargetsInternal { + public func publicFunc() {} +} + +// expected-error@+1 {{'AfterDeploymentTarget' is only available in}} expected-note@+1 {{add @available attribute to enclosing extension}} +extension AfterDeploymentTarget {} + +// expected-error@+1 {{'AfterDeploymentTarget' is only available in}} expected-note@+1 {{add @available attribute to enclosing extension}} +extension AfterDeploymentTarget { + internal func internalFunc1() {} + private func privateFunc1() {} + fileprivate func fileprivateFunc1() {} +} + +// expected-error@+1 {{'AfterDeploymentTarget' is only available in}} expected-note@+1 {{add @available attribute to enclosing extension}} +extension AfterDeploymentTarget { + public func publicFunc1() {} +} + + +// MARK: Protocol conformances + +internal protocol InternalProto {} + +extension NoAvailable: InternalProto {} +extension BeforeInliningTarget: InternalProto {} +extension AtInliningTarget: InternalProto {} +extension BetweenTargets: InternalProto {} +extension AtDeploymentTarget: InternalProto {} +extension AfterDeploymentTarget: InternalProto {} // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add @available attribute to enclosing extension}} + +public protocol PublicProto {} + +extension NoAvailable: PublicProto {} +extension BeforeInliningTarget: PublicProto {} +extension AtInliningTarget: PublicProto {} +extension BetweenTargets: PublicProto {} // expected-error {{'BetweenTargets' is only available in}} expected-note {{add @available attribute to enclosing extension}} +extension AtDeploymentTarget: PublicProto {} // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add @available attribute to enclosing extension}} +extension AfterDeploymentTarget: PublicProto {} // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add @available attribute to enclosing extension}} + + +// MARK: - Type aliases + +public typealias PublicNoAvailableAlias = NoAvailable +public typealias PublicBeforeInliningTargetAlias = BeforeInliningTarget +public typealias PublicAtInliningTargetAlias = AtInliningTarget +public typealias PublicBetweenTargetsAlias = BetweenTargets // expected-error {{'BetweenTargets' is only available in}} +public typealias PublicAtDeploymentTargetAlias = AtDeploymentTarget // expected-error {{'AtDeploymentTarget' is only available in}} +public typealias PublicAfterDeploymentTargetAlias = AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} + +typealias InternalNoAvailableAlias = NoAvailable +typealias InternalBeforeInliningTargetAlias = BeforeInliningTarget +typealias InternalAtInliningTargetAlias = AtInliningTarget +typealias InternalBetweenTargetsAlias = BetweenTargets +typealias InternalAtDeploymentTargetAlias = AtDeploymentTarget +typealias InternalAfterDeploymentTargetAlias = AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} + + +// MARK: - Top-level code + // Top-level code, if somehow present in a resilient module, is treated like // a non-inlinable function. defer { diff --git a/test/attr/attr_inlinable_available_maccatalyst.swift b/test/attr/attr_inlinable_available_maccatalyst.swift deleted file mode 100644 index cd0a00874e38f..0000000000000 --- a/test/attr/attr_inlinable_available_maccatalyst.swift +++ /dev/null @@ -1,567 +0,0 @@ -// This is the same test as attr_inlinable_available, but specifically using a -// macCatalyst target which has its own version floor separate from iOS. The two -// tests could be merged in the future if there were a CI bot running tests with -// OS=maccatalyst and there were a lit.py substitution for the -target argument -// that substituted to a macCatalyst SDK version compatible with the -// configuration of this test. - -// REQUIRES: maccatalyst_support - -// Primary execution of this test. Uses the default minimum inlining version, -// which is the version when Swift was introduced. -// RUN: %target-typecheck-verify-swift -swift-version 5 -enable-library-evolution -target %target-cpu-apple-ios14.4-macabi -target-min-inlining-version min - - -// FIXME: Re-enable with rdar://91387029 -// Check that `-library-level api` implies `-target-min-inlining-version min` -// RUN/: %target-typecheck-verify-swift -swift-version 5 -enable-library-evolution -target %target-cpu-apple-ios14.4-macabi -library-level api - - -// Check that these rules are only applied when requested and that at least some -// diagnostics are not present without it. -// RUN: not %target-typecheck-verify-swift -swift-version 5 -target %target-cpu-apple-ios14.4-macabi 2>&1 | %FileCheck --check-prefix NON_MIN %s - - -// Check that -target-min-inlining-version overrides -library-level, allowing -// library owners to disable this behavior for API libraries if needed. -// RUN: not %target-typecheck-verify-swift -swift-version 5 -target %target-cpu-apple-ios14.4-macabi -target-min-inlining-version target -library-level api 2>&1 | %FileCheck --check-prefix NON_MIN %s - - -// Check that we respect -target-min-inlining-version by cranking it up high -// enough to suppress any possible errors. -// RUN: %target-swift-frontend -typecheck -disable-objc-attr-requires-foundation-module %s -swift-version 5 -enable-library-evolution -target %target-cpu-apple-ios14.4-macabi -target-min-inlining-version 42.0 - - -// NON_MIN: error: expected error not produced -// NON_MIN: {'BetweenTargets' is only available in} - - -/// Declaration with no availability annotation. Should be inferred as minimum -/// inlining target. -public struct NoAvailable { - @usableFromInline internal init() {} -} - -@available(macCatalyst 12, *) -public struct BeforeInliningTarget { - @usableFromInline internal init() {} -} - -@available(macCatalyst 13.1, *) -public struct AtInliningTarget { - @usableFromInline internal init() {} -} - -@available(macCatalyst 14, *) -public struct BetweenTargets { - @usableFromInline internal init() {} -} - -@available(macCatalyst 14.4, *) -public struct AtDeploymentTarget { - @usableFromInline internal init() {} -} - -@available(macCatalyst 15, *) -public struct AfterDeploymentTarget { - @usableFromInline internal init() {} -} - - - -// -// Uses in resilient functions are based on the minimum deployment target -// (i.e. the -target). -// - -public func deployedUseNoAvailable( // expected-note 5 {{add @available attribute}} - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, // expected-error {{'BetweenTargets' is only available in}} - _: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in}} - _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -) { - defer { - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - - if #available(macCatalyst 15, *) { - _ = AfterDeploymentTarget() - } -} - -@available(macCatalyst 12, *) -public func deployedUseBeforeInliningTarget( - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, // expected-error {{'BetweenTargets' is only available in}} - _: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in}} - _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -) { - defer { - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - - if #available(macCatalyst 15, *) { - _ = AfterDeploymentTarget() - } -} - -@available(macCatalyst 13.1, *) -public func deployedUseAtInliningTarget( - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, // expected-error {{'BetweenTargets' is only available in}} - _: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in}} - _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -) { - defer { - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - - if #available(macCatalyst 15, *) { - _ = AfterDeploymentTarget() - } -} - -@available(macCatalyst 14, *) -public func deployedUseBetweenTargets( - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, - _: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in}} - _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -) { - defer { - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - - if #available(macCatalyst 15, *) { - _ = AfterDeploymentTarget() - } -} - -@available(macCatalyst 14.4, *) -public func deployedUseAtDeploymentTarget( - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, - _: AtDeploymentTarget, - _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -) { - defer { - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - - if #available(macCatalyst 15, *) { - _ = AfterDeploymentTarget() - } -} - -@available(macCatalyst 15, *) -public func deployedUseAfterDeploymentTarget( - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, - _: AtDeploymentTarget, - _: AfterDeploymentTarget -) { - defer { - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() -} - - - -// -// Uses in inlinable functions are based on the minimum inlining target -// - -@inlinable public func inlinedUseNoAvailable( // expected-note 8 {{add @available attribute}} - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, // expected-error {{'BetweenTargets' is only available in}} - _: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in}} - _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -) { - defer { - _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in}} expected-note {{add 'if #available'}} - _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - - if #available(macCatalyst 14, *) { - _ = BetweenTargets() - } - if #available(macCatalyst 14.4, *) { - _ = AtDeploymentTarget() - } - if #available(macCatalyst 15, *) { - _ = AfterDeploymentTarget() - } -} - -@available(macCatalyst 12, *) -@inlinable public func inlinedUseBeforeInliningTarget( - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, // expected-error {{'BetweenTargets' is only available in}} - _: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in}} - _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -) { - defer { - _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in}} expected-note {{add 'if #available'}} - _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - - if #available(macCatalyst 14, *) { - _ = BetweenTargets() - } - if #available(macCatalyst 14.4, *) { - _ = AtDeploymentTarget() - } - if #available(macCatalyst 15, *) { - _ = AfterDeploymentTarget() - } -} - -@available(macCatalyst 13.1, *) -@inlinable public func inlinedUseAtInliningTarget( - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, // expected-error {{'BetweenTargets' is only available in}} - _: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in}} - _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -) { - defer { - _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in}} expected-note {{add 'if #available'}} - _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - - if #available(macCatalyst 14, *) { - _ = BetweenTargets() - } - if #available(macCatalyst 14.4, *) { - _ = AtDeploymentTarget() - } - if #available(macCatalyst 15, *) { - _ = AfterDeploymentTarget() - } -} - -@available(macCatalyst 14, *) -@inlinable public func inlinedUseBetweenTargets( - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, - _: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in}} - _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -) { - defer { - _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() - _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - - if #available(macCatalyst 14.4, *) { - _ = AtDeploymentTarget() - } - if #available(macCatalyst 15, *) { - _ = AfterDeploymentTarget() - } -} - -@available(macCatalyst 14.4, *) -@inlinable public func inlinedUseAtDeploymentTarget( - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, - _: AtDeploymentTarget, - _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -) { - defer { - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - - if #available(macCatalyst 15, *) { - _ = AfterDeploymentTarget() - } -} - -@available(macCatalyst 15, *) -@inlinable public func inlinedUseAfterDeploymentTarget( - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, - _: AtDeploymentTarget, - _: AfterDeploymentTarget -) { - defer { - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() -} - -// -// Edge cases. -// - -// Internal functions should use the minimum deployment target. - -internal func fn() { - _ = AtDeploymentTarget() -} - -// @_alwaysEmitIntoClient acts like @inlinable. - -@_alwaysEmitIntoClient public func aEICUseNoAvailable( // expected-note 8 {{add @available attribute}} - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, // expected-error {{'BetweenTargets' is only available in}} - _: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in}} - _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -) { - defer { - _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in}} expected-note {{add 'if #available'}} - _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - - if #available(macCatalyst 14, *) { - _ = BetweenTargets() - } - if #available(macCatalyst 14.4, *) { - _ = AtDeploymentTarget() - } - if #available(macCatalyst 15, *) { - _ = AfterDeploymentTarget() - } -} - -// @_backDeploy acts like @inlinable. - -@available(macCatalyst 13.1, *) -@_backDeploy(before: macCatalyst 999.0) -public func backDeployedToInliningTarget( - _: NoAvailable, - _: BeforeInliningTarget, - _: AtInliningTarget, - _: BetweenTargets, // expected-error {{'BetweenTargets' is only available in}} - _: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in}} - _: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -) { - defer { - _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - } - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in}} expected-note {{add 'if #available'}} - _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - - if #available(macCatalyst 14, *) { - _ = BetweenTargets() - } - if #available(macCatalyst 14.4, *) { - _ = AtDeploymentTarget() - } - if #available(macCatalyst 15, *) { - _ = AfterDeploymentTarget() - } -} - -// Default arguments act like @inlinable. - -public func defaultArgsUseNoAvailable( // expected-note 3 {{add @available attribute}} - _: Any = NoAvailable.self, - _: Any = BeforeInliningTarget.self, - _: Any = AtInliningTarget.self, - _: Any = BetweenTargets.self, // expected-error {{'BetweenTargets' is only available in}} - _: Any = AtDeploymentTarget.self, // expected-error {{'AtDeploymentTarget' is only available in}} - _: Any = AfterDeploymentTarget.self // expected-error {{'AfterDeploymentTarget' is only available in}} -) {} - -public struct PublicStruct { // expected-note 6 {{add @available attribute}} - // Public declarations act like @inlinable. - public var aPublic: NoAvailable - public var bPublic: BeforeInliningTarget - public var cPublic: AtInliningTarget - public var dPublic: BetweenTargets // expected-error {{'BetweenTargets' is only available in}} - public var ePublic: AtDeploymentTarget // expected-error {{'AtDeploymentTarget' is only available in}} - public var fPublic: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} - - // Internal declarations act like non-inlinable. - var aInternal: NoAvailable - var bInternal: BeforeInliningTarget - var cInternal: AtInliningTarget - var dInternal: BetweenTargets - var eInternal: AtDeploymentTarget - var fInternal: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} - - @available(macCatalyst 14, *) - public internal(set) var internalSetter: Void { - @inlinable get { - // Public inlinable getter acts like @inlinable - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() - _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in}} - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - - } - set { - // Private setter acts like non-inlinable - _ = NoAvailable() - _ = BeforeInliningTarget() - _ = AtInliningTarget() - _ = BetweenTargets() - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - } - } -} - -@frozen public struct FrozenPublicStruct { // expected-note 6 {{add @available attribute}} - // Public declarations act like @inlinable. - public var aPublic: NoAvailable - public var bPublic: BeforeInliningTarget - public var cPublic: AtInliningTarget - public var dPublic: BetweenTargets // expected-error {{'BetweenTargets' is only available in}} - public var ePublic: AtDeploymentTarget // expected-error {{'AtDeploymentTarget' is only available in}} - public var fPublic: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} - - // Internal declarations act like @inlinable in a frozen struct. - var aInternal: NoAvailable - var bInternal: BeforeInliningTarget - var cInternal: AtInliningTarget - var dInternal: BetweenTargets // expected-error {{'BetweenTargets' is only available in}} - var eInternal: AtDeploymentTarget // expected-error {{'AtDeploymentTarget' is only available in}} - var fInternal: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -} - -internal struct InternalStruct { // expected-note {{add @available attribute}} - // Internal declarations act like non-inlinable. - var aInternal: NoAvailable - var bInternal: BeforeInliningTarget - var cInternal: AtInliningTarget - var dInternal: BetweenTargets - var eInternal: AtDeploymentTarget - var fInternal: AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in}} -} - -// Top-level code, if somehow present in a resilient module, is treated like -// a non-inlinable function. -defer { - _ = AtDeploymentTarget() - _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} -} -_ = NoAvailable() -_ = BeforeInliningTarget() -_ = AtInliningTarget() -_ = BetweenTargets() -_ = AtDeploymentTarget() -_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in}} expected-note {{add 'if #available'}} - -if #available(macCatalyst 15, *) { - _ = AfterDeploymentTarget() -} - -