AST: Allow overloads to be disambiguated by obsoletion version.

Previously, whether a declaration is unavailable because it is obsolete was
determined based solely on the deployment target and not based on contextual
availability. Taking contextual availability into account makes availability
checking more internally consistent and allows library authors to evolve APIs
by obsoleting the previous declaration while introducing a new declaration in the
same version:

```
@available(macOS, obsoleted: 15)
func foo(_ x: Int) { }

@available(macOS, introduced: 15)
func foo(_ x: Int, y: Int = 0) { }

foo(42) // unambiguous, regardless of contextual version of macOS
```

This change primarily accepts more code that wasn't accepted previously, but it
could also be source breaking for some code that was previously allowed to use
obsoleted declarations in contexts that will always run on OS versions where
the declaration is obsolete. That code was clearly taking advantage of an
availabilty loophole, though, and in practice I don't expect it to be common.

Resolves rdar://144647964.
This commit is contained in:
Allan Shortlidge
2025-08-12 14:56:28 -07:00
parent 6e3361eb53
commit 93902835d0
6 changed files with 88 additions and 79 deletions

View File

@@ -205,26 +205,23 @@ getAvailabilityConstraintForAttr(const Decl *decl,
auto &ctx = decl->getASTContext();
auto domain = attr.getDomain();
auto deploymentRange = domain.getDeploymentRange(ctx);
bool domainSupportsRefinement = domain.supportsContextRefinement();
std::optional<AvailabilityRange> availableRange =
domainSupportsRefinement ? context.getAvailabilityRange(domain, ctx)
: deploymentRange;
// Is the decl obsoleted in the deployment context?
// Is the decl obsoleted in this context?
if (auto obsoletedRange = attr.getObsoletedRange(ctx)) {
if (deploymentRange && deploymentRange->isContainedIn(*obsoletedRange))
if (availableRange && availableRange->isContainedIn(*obsoletedRange))
return AvailabilityConstraint::unavailableObsolete(attr);
}
// Is the decl not yet introduced in the local context?
// Is the decl not yet introduced in this context?
if (auto introducedRange = attr.getIntroducedRange(ctx)) {
if (domain.supportsContextRefinement()) {
auto availableRange = context.getAvailabilityRange(domain, ctx);
if (!availableRange || !availableRange->isContainedIn(*introducedRange))
return AvailabilityConstraint::unintroduced(attr);
return std::nullopt;
}
// Is the decl not yet introduced in the deployment context?
if (deploymentRange && !deploymentRange->isContainedIn(*introducedRange))
return AvailabilityConstraint::unavailableUnintroduced(attr);
if (!availableRange || !availableRange->isContainedIn(*introducedRange))
return domainSupportsRefinement
? AvailabilityConstraint::unintroduced(attr)
: AvailabilityConstraint::unavailableUnintroduced(attr);
}
return std::nullopt;

View File

@@ -355,10 +355,13 @@ void AvailabilityContext::constrainWithDecl(const Decl *decl) {
void AvailabilityContext::constrainWithDeclAndPlatformRange(
const Decl *decl, const AvailabilityRange &otherPlatformRange) {
auto &ctx = decl->getASTContext();
// Constrain the platform range first since this may have an effect on
// whether the decl is considered obsolete.
constrainWithPlatformRange(otherPlatformRange, ctx);
bool isConstrained = false;
auto platformRange = storage->platformRange;
isConstrained |= constrainRange(platformRange, otherPlatformRange);
bool isDeprecated = storage->isDeprecated;
isConstrained |= constrainBool(isDeprecated, decl->isDeprecated());

View File

@@ -18,6 +18,7 @@
#include "swift/AST/ASTContext.h"
#include "swift/AST/ASTWalker.h"
#include "swift/AST/AvailabilityConstraint.h"
#include "swift/AST/AvailabilityInference.h"
#include "swift/AST/AvailabilitySpec.h"
#include "swift/AST/Decl.h"
@@ -461,10 +462,17 @@ private:
// As a convenience, explicitly unavailable decls are constrained to the
// deployment target. There's not much benefit to checking these decls at a
// lower availability version floor since they can't be invoked by clients.
if (getCurrentScope()->getAvailabilityContext().isUnavailable() ||
decl->isUnavailable())
auto context = getCurrentScope()->getAvailabilityContext();
if (context.isUnavailable())
return true;
// Check whether the decl is unavailable relative to the current context.
if (auto constraint = getAvailabilityConstraintsForDecl(decl, context)
.getPrimaryConstraint()) {
if (constraint->isUnavailable())
return true;
}
// To remain compatible with a lot of existing SPIs that are declared
// without availability attributes, constrain them to the deployment target
// too.
@@ -584,8 +592,7 @@ private:
}
void buildContextsForBodyOfDecl(Decl *decl) {
// Are we already constrained by the deployment target and the declaration
// doesn't explicitly allow unsafe constructs in its definition, adding
// If we are already constrained by the deployment target then adding
// new contexts won't change availability.
if (isCurrentScopeContainedByDeploymentTarget())
return;
@@ -599,8 +606,10 @@ private:
// Apply deployment-target availability if appropriate for this body.
if (!isCurrentScopeContainedByDeploymentTarget() &&
bodyIsDeploymentTarget(decl)) {
availability.constrainWithPlatformRange(
AvailabilityRange::forDeploymentTarget(Context), Context);
// Also constrain availability with the decl itself to handle the case
// where the decl becomes obsolete at the deployment target.
availability.constrainWithDeclAndPlatformRange(
decl, AvailabilityRange::forDeploymentTarget(Context));
}
nodesAndScopes.push_back(

View File

@@ -185,8 +185,8 @@ public func deployedUseNoAvailable( // expected-note 5 {{add '@available' attrib
_: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: ObsoletedBetweenTargets, // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_: ObsoletedAtDeploymentTarget, // expected-error {{'ObsoletedAtDeploymentTarget' is unavailable in macOS}}
_: ObsoletedBetweenTargets,
_: ObsoletedAtDeploymentTarget,
) {
defer {
_ = AtDeploymentTarget()
@@ -214,8 +214,8 @@ public func deployedUseBeforeInliningTarget(
_: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: ObsoletedBetweenTargets, // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_: ObsoletedAtDeploymentTarget, // expected-error {{'ObsoletedAtDeploymentTarget' is unavailable in macOS}}
_: ObsoletedBetweenTargets,
_: ObsoletedAtDeploymentTarget,
) {
defer {
_ = AtDeploymentTarget()
@@ -243,8 +243,8 @@ public func deployedUseAtInliningTarget(
_: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: ObsoletedBetweenTargets, // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_: ObsoletedAtDeploymentTarget, // expected-error {{'ObsoletedAtDeploymentTarget' is unavailable in macOS}}
_: ObsoletedBetweenTargets,
_: ObsoletedAtDeploymentTarget,
) {
defer {
_ = AtDeploymentTarget()
@@ -273,7 +273,7 @@ public func deployedUseBetweenTargets(
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: ObsoletedBetweenTargets, // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_: ObsoletedAtDeploymentTarget, // expected-error {{'ObsoletedAtDeploymentTarget' is unavailable in macOS}}
_: ObsoletedAtDeploymentTarget,
) {
defer {
_ = AtDeploymentTarget()
@@ -445,12 +445,12 @@ public func obsoletedBetweenTargets(
_: NoAvailable,
_: BeforeInliningTarget,
_: AtInliningTarget,
_: BetweenTargets,
_: AtDeploymentTarget,
_: AfterDeploymentTarget,
_: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: ObsoletedBetweenTargets,
_: ObsoletedAtDeploymentTarget,
_: Unavailable
_: Unavailable, // expected-error {{'Unavailable' is unavailable in macOS}}
) {
defer {
_ = AtDeploymentTarget()
@@ -476,12 +476,12 @@ public func obsoletedAtDeploymentTarget(
_: NoAvailable,
_: BeforeInliningTarget,
_: AtInliningTarget,
_: BetweenTargets,
_: AtDeploymentTarget,
_: AfterDeploymentTarget,
_: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: ObsoletedBetweenTargets,
_: ObsoletedAtDeploymentTarget,
_: Unavailable
_: Unavailable // expected-error {{'Unavailable' is unavailable in macOS}}
) {
defer {
_ = AtDeploymentTarget()
@@ -510,8 +510,8 @@ public func obsoletedAfterDeploymentTarget(
_: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: ObsoletedBetweenTargets, // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_: ObsoletedAtDeploymentTarget, // expected-error {{'ObsoletedAtDeploymentTarget' is unavailable in macOS}}
_: ObsoletedBetweenTargets,
_: ObsoletedAtDeploymentTarget,
_: Unavailable, // expected-error {{'Unavailable' is unavailable in macOS}}
) {
defer {
@@ -576,12 +576,12 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
_: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: ObsoletedBetweenTargets, // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_: ObsoletedBetweenTargets,
) {
defer {
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_ = ObsoletedBetweenTargets()
}
_ = NoAvailable()
_ = BeforeInliningTarget()
@@ -589,7 +589,7 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
_ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_ = ObsoletedBetweenTargets()
if #available(macOS 10.14.5, *) {
_ = BetweenTargets()
@@ -608,7 +608,7 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
defer {
let _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
let _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
let _ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
let _ = ObsoletedBetweenTargets()
}
let _ = NoAvailable()
@@ -617,7 +617,7 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
let _ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
let _ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
let _ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
let _ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
let _ = ObsoletedBetweenTargets()
if #available(macOS 10.14.5, *) {
let _ = BetweenTargets()
@@ -641,12 +641,12 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
_: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: ObsoletedBetweenTargets, // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_: ObsoletedBetweenTargets,
) {
defer {
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_ = ObsoletedBetweenTargets()
}
_ = NoAvailable()
_ = BeforeInliningTarget()
@@ -654,7 +654,7 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
_ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_ = ObsoletedBetweenTargets()
if #available(macOS 10.14.5, *) {
_ = BetweenTargets()
@@ -678,12 +678,12 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
_: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: ObsoletedBetweenTargets, // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_: ObsoletedBetweenTargets,
) {
defer {
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_ = ObsoletedBetweenTargets()
}
_ = NoAvailable()
_ = BeforeInliningTarget()
@@ -691,7 +691,7 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
_ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_ = ObsoletedBetweenTargets()
if #available(macOS 10.14.5, *) {
_ = BetweenTargets()
@@ -1002,12 +1002,12 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
_: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: ObsoletedBetweenTargets, // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_: ObsoletedBetweenTargets,
) {
defer {
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_ = ObsoletedBetweenTargets()
}
_ = NoAvailable()
_ = BeforeInliningTarget()
@@ -1015,7 +1015,7 @@ public func spiDeployedUseNoAvailable( // expected-note 3 {{add '@available' att
_ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_ = ObsoletedBetweenTargets()
if #available(macOS 10.14.5, *) {
_ = BetweenTargets()
@@ -1045,12 +1045,12 @@ public func backDeployedToInliningTarget(
_: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: ObsoletedBetweenTargets, // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_: ObsoletedBetweenTargets,
) {
defer {
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_ = ObsoletedBetweenTargets()
}
_ = NoAvailable()
_ = BeforeInliningTarget()
@@ -1058,7 +1058,7 @@ public func backDeployedToInliningTarget(
_ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_ = ObsoletedBetweenTargets()
if #available(macOS 10.14.5, *) {
_ = BetweenTargets()
@@ -1086,7 +1086,7 @@ public func defaultArgsUseNoAvailable( // expected-note 3 {{add '@available' att
_: Any = BetweenTargets.self, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
_: Any = AtDeploymentTarget.self, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: Any = AfterDeploymentTarget.self, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: Any = ObsoletedBetweenTargets.self, // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_: Any = ObsoletedBetweenTargets.self,
) {}
func defaultArgsUseInternal( // expected-note {{add '@available' attribute}}
@@ -1132,7 +1132,7 @@ public func defaultArgsClosureExprNoAvailable( // expected-note 3 {{add '@availa
_ = BetweenTargets.self // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available' version check}}
_ = AtDeploymentTarget.self // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available' version check}}
_ = AfterDeploymentTarget.self // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available' version check}}
_ = ObsoletedBetweenTargets.self // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_ = ObsoletedBetweenTargets.self
if #available(macOS 10.14.5, *) {
_ = BetweenTargets.self
}
@@ -1181,7 +1181,7 @@ public struct PublicStruct { // expected-note 21 {{add '@available' attribute}}
dPublic: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
ePublic: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
fPublic: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
gPublic: ObsoletedBetweenTargets // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
gPublic: ObsoletedBetweenTargets
@available(macOS 10.14.5, *)
public var aPublicAvailBetween: NoAvailable,
@@ -1327,7 +1327,7 @@ public struct PublicStruct { // expected-note 21 {{add '@available' attribute}}
_ = BetweenTargets() // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available' version check}}
_ = AtDeploymentTarget() // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add 'if #available'}}
_ = AfterDeploymentTarget() // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add 'if #available'}}
_ = ObsoletedBetweenTargets() // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_ = ObsoletedBetweenTargets()
if #available(macOS 10.15, *) {
_ = AtDeploymentTarget()
@@ -1544,7 +1544,7 @@ extension NoAvailable { // expected-note 3 {{add '@available' attribute to enclo
_: BetweenTargets, // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
_: AtDeploymentTarget, // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
_: AfterDeploymentTarget, // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
_: ObsoletedBetweenTargets, // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
_: ObsoletedBetweenTargets,
) {}
}
@@ -1802,7 +1802,7 @@ extension AtInliningTarget: PublicProto {}
extension BetweenTargets: PublicProto {}
extension AtDeploymentTarget: PublicProto {}
extension AfterDeploymentTarget: PublicProto {} // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add '@available' attribute to enclosing extension}}
extension ObsoletedBetweenTargets: PublicProto {} // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
extension ObsoletedBetweenTargets: PublicProto {}
// MARK: - Associated types
@@ -1817,7 +1817,7 @@ public protocol NoAvailableProtoWithAssoc { // expected-note 3 {{add '@available
// expected-note@-1{{add '@available' attribute to enclosing associated type}}
associatedtype F: AfterDeploymentTargetProto // expected-error {{'AfterDeploymentTargetProto' is only available in}}
// expected-note@-1{{add '@available' attribute to enclosing associated type}}
associatedtype G: ObsoletedBetweenTargetsProto // expected-error {{'ObsoletedBetweenTargetsProto' is unavailable in macOS}}
associatedtype G: ObsoletedBetweenTargetsProto
}
@available(macOS 10.9, *)
@@ -1831,7 +1831,7 @@ public protocol BeforeInliningTargetProtoWithAssoc {
// expected-note@-1{{add '@available' attribute to enclosing associated type}}
associatedtype F: AfterDeploymentTargetProto // expected-error {{'AfterDeploymentTargetProto' is only available in}}
// expected-note@-1{{add '@available' attribute to enclosing associated type}}
associatedtype G: ObsoletedBetweenTargetsProto // expected-error {{'ObsoletedBetweenTargetsProto' is unavailable in macOS}}
associatedtype G: ObsoletedBetweenTargetsProto
}
@available(macOS 10.10, *)
@@ -1845,7 +1845,7 @@ public protocol AtInliningTargetProtoWithAssoc {
// expected-note@-1{{add '@available' attribute to enclosing associated type}}
associatedtype F: AfterDeploymentTargetProto // expected-error {{'AfterDeploymentTargetProto' is only available in}}
// expected-note@-1{{add '@available' attribute to enclosing associated type}}
associatedtype G: ObsoletedBetweenTargetsProto // expected-error {{'ObsoletedBetweenTargetsProto' is unavailable in macOS}}
associatedtype G: ObsoletedBetweenTargetsProto
}
@available(macOS 10.14.5, *)
@@ -1917,7 +1917,7 @@ public enum PublicNoAvailableEnumWithTypeAliases { // expected-note 3 {{add '@av
public typealias D = BetweenTargets // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add '@available' attribute to enclosing type alias}}
public typealias E = AtDeploymentTarget // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note {{add '@available' attribute to enclosing type alias}}
public typealias F = AfterDeploymentTarget // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}} expected-note {{add '@available' attribute to enclosing type alias}}
public typealias G = ObsoletedBetweenTargets // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
public typealias G = ObsoletedBetweenTargets
}
@available(macOS, unavailable)
@@ -1962,7 +1962,7 @@ public enum PublicNoAvailableEnumWithPayloads { // expected-note 5 {{add '@avail
dNoAvailable(BetweenTargets), // expected-error {{'BetweenTargets' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}}
eNoAvailable(AtDeploymentTarget), // expected-error {{'AtDeploymentTarget' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}}
fNoAvailable(AfterDeploymentTarget), // expected-error {{'AfterDeploymentTarget' is only available in macOS 11 or newer}}
gNoAvailable(ObsoletedBetweenTargets) // expected-error {{'ObsoletedBetweenTargets' is unavailable in macOS}}
gNoAvailable(ObsoletedBetweenTargets)
@available(macOS, introduced: 10.15)
case aAtDeploymentTarget(NoAvailable),
@@ -2004,7 +2004,7 @@ public enum NoAvailableEnumWithClasses {
public class InheritsBetweenTargets: BetweenTargetsClass {} // expected-error {{'BetweenTargetsClass' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note 2 {{add '@available' attribute to enclosing class}}
public class InheritsAtDeploymentTarget: AtDeploymentTargetClass {} // expected-error {{'AtDeploymentTargetClass' is only available in macOS 10.15 or newer; clients of 'Test' may have a lower deployment target}} expected-note 2 {{add '@available' attribute to enclosing class}}
public class InheritsAfterDeploymentTarget: AfterDeploymentTargetClass {} // expected-error {{'AfterDeploymentTargetClass' is only available in macOS 11 or newer}} expected-note 2 {{add '@available' attribute to enclosing class}}
public class InheritsObsoletedBetweenTargetsClass: ObsoletedBetweenTargetsClass {} // expected-error {{'ObsoletedBetweenTargetsClass' is unavailable in macOS}}
public class InheritsObsoletedBetweenTargetsClass: ObsoletedBetweenTargetsClass {}
@usableFromInline
class UFIInheritsBetweenTargets: BetweenTargetsClass {} // expected-error {{'BetweenTargetsClass' is only available in macOS 10.14.5 or newer; clients of 'Test' may have a lower deployment target}} expected-note 2 {{add '@available' attribute to enclosing class}}
@@ -2054,7 +2054,7 @@ public class Base {
public func afterDeploymentTargetMethod() {}// expected-note {{overridden declaration is here}}
@available(macOS, obsoleted: 10.14.5)
public func obsoletedBetweenTargetsMethod() {}
public func obsoletedBetweenTargetsMethod() {} // expected-note 3 {{overridden declaration is here}}
// expected-note@-1 * {{'obsoletedBetweenTargetsMethod()' has been explicitly marked unavailable here}}
}
@@ -2064,7 +2064,7 @@ public class DerivedNoAvailable: Base {
public override func betweenTargetsMethod() {}
public override func atDeploymentTargetMethod() {}
public override func afterDeploymentTargetMethod() {}
public override func obsoletedBetweenTargetsMethod() {} // expected-error {{cannot override 'obsoletedBetweenTargetsMethod' which has been marked unavailable}}
public override func obsoletedBetweenTargetsMethod() {}
}
@available(macOS 10.9, *)
@@ -2080,7 +2080,7 @@ public class DerivedBeforeInliningTarget: Base {
@available(macOS 10.9, *)
public override func afterDeploymentTargetMethod() {}
@available(macOS 10.9, *)
public override func obsoletedBetweenTargetsMethod() {} // expected-error {{cannot override 'obsoletedBetweenTargetsMethod' which has been marked unavailable}}
public override func obsoletedBetweenTargetsMethod() {}
}
@available(macOS 10.10, *)
@@ -2096,7 +2096,7 @@ public class DerivedAtInliningTarget: Base {
@available(macOS 10.10, *)
public override func afterDeploymentTargetMethod() {}
@available(macOS 10.10, *)
public override func obsoletedBetweenTargetsMethod() {} // expected-error {{cannot override 'obsoletedBetweenTargetsMethod' which has been marked unavailable}}
public override func obsoletedBetweenTargetsMethod() {}
}
@available(macOS 10.14.5, *)
@@ -2164,7 +2164,7 @@ public class DerivedAtDeploymentTargetOverrides: Base {
public override func afterDeploymentTargetMethod() {}
@available(macOS 10.15, *)
public override func obsoletedBetweenTargetsMethod() {} // expected-error {{cannot override 'obsoletedBetweenTargetsMethod' which has been marked unavailable}}
public override func obsoletedBetweenTargetsMethod() {} // expected-error {{overriding 'obsoletedBetweenTargetsMethod' must be as available as declaration it overrides}}
}
public class DerivedFutureOverrides: Base {
@@ -2184,7 +2184,7 @@ public class DerivedFutureOverrides: Base {
public override func afterDeploymentTargetMethod() {} // expected-error {{overriding 'afterDeploymentTargetMethod' must be as available as declaration it overrides}}
@available(macOS 12, *)
public override func obsoletedBetweenTargetsMethod() {} // expected-error {{cannot override 'obsoletedBetweenTargetsMethod' which has been marked unavailable}}
public override func obsoletedBetweenTargetsMethod() {} // expected-error {{overriding 'obsoletedBetweenTargetsMethod' must be as available as declaration it overrides}}
}
extension AtDeploymentTarget {
@@ -2225,6 +2225,6 @@ extension AtDeploymentTarget {
public override func afterDeploymentTargetMethod() {}
@available(macOS 11, *)
public override func obsoletedBetweenTargetsMethod() {} // expected-error {{cannot override 'obsoletedBetweenTargetsMethod' which has been marked unavailable}}
public override func obsoletedBetweenTargetsMethod() {} // expected-error {{overriding 'obsoletedBetweenTargetsMethod' must be as available as declaration it overrides}}
}
}

View File

@@ -144,7 +144,7 @@ func globalFuncDeprecatedAndAvailableOn51() -> Int { return 51 }
func globalFuncAvailableOn51Deprecated52() -> Int { return 51 }
@available(OSX, introduced: 51, obsoleted: 52)
func globalFuncAvailableOn51Obsoleted52() -> Int { return 51 }
func globalFuncAvailableOn51Obsoleted52() -> Int { return 51 } // expected-note {{'globalFuncAvailableOn51Obsoleted52()' was obsoleted in macOS 52}}
@available(OSX, unavailable, introduced: 51)
func globalFuncUnavailableAndIntroducedOn51() -> Int { return 51 } // expected-note 3 {{'globalFuncUnavailableAndIntroducedOn51()' has been explicitly marked unavailable here}}
@@ -168,7 +168,7 @@ if #available(OSX 51, *) {
if #available(OSX 52, *) {
let _ = globalFuncDeprecatedAndAvailableOn51() // expected-warning {{'globalFuncDeprecatedAndAvailableOn51()' is deprecated in macOS}}
let _ = globalFuncAvailableOn51Deprecated52()
let _ = globalFuncAvailableOn51Obsoleted52()
let _ = globalFuncAvailableOn51Obsoleted52() // expected-error {{'globalFuncAvailableOn51Obsoleted52()' is unavailable in macOS}}
let _ = globalFuncUnavailableAndIntroducedOn51() // expected-error {{'globalFuncUnavailableAndIntroducedOn51()' is unavailable in macOS}}
}

View File

@@ -55,7 +55,7 @@ func test_introduced_vs_obsoleted(_ s: S) {
s.baz(42)
// CHECK: function_ref @$ss26_stdlib_isOSVersionAtLeastyBi1_Bw_BwBwtF :
if #available(macOS 999, *) {
// CHECK: function_ref @$s29availability_with_overloading1SV3bazyySiF :
// CHECK: function_ref @$s29availability_with_overloading1SV3bazyySi_SitF :
s.baz(42)
}
}
@@ -63,6 +63,6 @@ func test_introduced_vs_obsoleted(_ s: S) {
// CHECK-LABEL: sil {{.*}} @$s29availability_with_overloading29test_introduced_vs_obsoleted2yyAA1SVF :
@available(macOS 999, *)
func test_introduced_vs_obsoleted2(_ s: S) {
// CHECK: function_ref @$s29availability_with_overloading1SV3bazyySiF :
// CHECK: function_ref @$s29availability_with_overloading1SV3bazyySi_SitF :
s.baz(42)
}