Skip to content

Commit 974767e

Browse files
authored
Merge pull request swiftlang#79734 from tshortli/availability-context-gardening
Gardening: `AvailabilityContext` and `AvailabilityConstraint` cleanup
2 parents bd67268 + dc2fe53 commit 974767e

8 files changed

+71
-66
lines changed

include/swift/AST/AvailabilityConstraint.h

+21-20
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,21 @@ class AvailabilityConstraint {
5151
/// constraint.
5252
Obsoleted,
5353

54-
/// The declaration is only available in a later version. For example,
55-
/// the declaration might only be introduced in the Swift 6 language mode
56-
/// while the module is being compiled in the Swift 5 language mode.
57-
IntroducedInLaterVersion,
58-
59-
/// The declaration is referenced in a context that does not have an
60-
/// adequate minimum version constraint. For example, a reference to a
61-
/// declaration that is introduced in macOS 13 from a context that may
62-
/// execute on earlier versions of macOS has this constraint. This
63-
/// kind of constraint can be satisfied by tightening the minimum
64-
/// version of the context with `if #available(...)` or by adding or
65-
/// adjusting an `@available` attribute.
66-
IntroducedInLaterDynamicVersion,
54+
/// The declaration is not available in the deployment configuration
55+
/// specified for this compilation. For example, the declaration might only
56+
/// be introduced in the Swift 6 language mode while the module is being
57+
/// compiled in the Swift 5 language mode. These availability constraints
58+
/// cannot be satisfied by adding constraining contextual availability using
59+
/// `@available` attributes or `if #available` queries.
60+
UnavailableForDeployment,
61+
62+
/// The declaration is referenced in a context that does not have adequate
63+
/// availability constraints. For example, a reference to a declaration that
64+
/// was introduced in macOS 13 from a context that may execute on earlier
65+
/// versions of macOS cannot satisfy this constraint. The constraint
66+
/// can be satisfied, though, by introducing an `@available` attribute or an
67+
/// `if #available(...)` query.
68+
PotentiallyUnavailable,
6769
};
6870

6971
/// Classifies constraints into different high level categories.
@@ -93,14 +95,13 @@ class AvailabilityConstraint {
9395
}
9496

9597
static AvailabilityConstraint
96-
introducedInLaterVersion(SemanticAvailableAttr attr) {
97-
return AvailabilityConstraint(Reason::IntroducedInLaterVersion, attr);
98+
unavailableForDeployment(SemanticAvailableAttr attr) {
99+
return AvailabilityConstraint(Reason::UnavailableForDeployment, attr);
98100
}
99101

100102
static AvailabilityConstraint
101-
introducedInLaterDynamicVersion(SemanticAvailableAttr attr) {
102-
return AvailabilityConstraint(Reason::IntroducedInLaterDynamicVersion,
103-
attr);
103+
potentiallyUnavailable(SemanticAvailableAttr attr) {
104+
return AvailabilityConstraint(Reason::PotentiallyUnavailable, attr);
104105
}
105106

106107
Reason getReason() const { return attrAndReason.getInt(); }
@@ -112,9 +113,9 @@ class AvailabilityConstraint {
112113
switch (getReason()) {
113114
case Reason::UnconditionallyUnavailable:
114115
case Reason::Obsoleted:
115-
case Reason::IntroducedInLaterVersion:
116+
case Reason::UnavailableForDeployment:
116117
return Kind::Unavailable;
117-
case Reason::IntroducedInLaterDynamicVersion:
118+
case Reason::PotentiallyUnavailable:
118119
return Kind::PotentiallyAvailable;
119120
}
120121
}

include/swift/AST/AvailabilityContext.h

+8-7
Original file line numberDiff line numberDiff line change
@@ -52,16 +52,16 @@ class AvailabilityContext {
5252
/// Retrieves an `AvailabilityContext` constrained by the given platform
5353
/// availability range.
5454
static AvailabilityContext forPlatformRange(const AvailabilityRange &range,
55-
ASTContext &ctx);
55+
const ASTContext &ctx);
5656

5757
/// Retrieves the maximally available `AvailabilityContext` for the
5858
/// compilation. The platform availability range will be set to the minimum
5959
/// inlining target (which may just be the deployment target).
60-
static AvailabilityContext forInliningTarget(ASTContext &ctx);
60+
static AvailabilityContext forInliningTarget(const ASTContext &ctx);
6161

6262
/// Retrieves an `AvailabilityContext` with the platform availability range
6363
/// set to the deployment target.
64-
static AvailabilityContext forDeploymentTarget(ASTContext &ctx);
64+
static AvailabilityContext forDeploymentTarget(const ASTContext &ctx);
6565

6666
/// Returns the range of platform versions which may execute code in the
6767
/// availability context, starting at its introduction version.
@@ -77,16 +77,17 @@ class AvailabilityContext {
7777
bool isDeprecated() const;
7878

7979
/// Constrain with another `AvailabilityContext`.
80-
void constrainWithContext(const AvailabilityContext &other, ASTContext &ctx);
80+
void constrainWithContext(const AvailabilityContext &other,
81+
const ASTContext &ctx);
8182

8283
/// Constrain the platform availability range with `platformRange`.
8384
void constrainWithPlatformRange(const AvailabilityRange &platformRange,
84-
ASTContext &ctx);
85+
const ASTContext &ctx);
8586

8687
/// Constrain the context by adding \p domain to the set of unavailable
8788
/// domains.
8889
void constrainWithUnavailableDomain(AvailabilityDomain domain,
89-
ASTContext &ctx);
90+
const ASTContext &ctx);
9091

9192
/// Constrain with the availability attributes of `decl`.
9293
void constrainWithDecl(const Decl *decl);
@@ -114,7 +115,7 @@ class AvailabilityContext {
114115
SWIFT_DEBUG_DUMP;
115116

116117
/// Returns true if all internal invariants are satisfied.
117-
bool verify(ASTContext &ctx) const;
118+
bool verify(const ASTContext &ctx) const;
118119
};
119120

120121
} // end namespace swift

include/swift/AST/AvailabilityContextStorage.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class DeclAvailabilityConstraints;
2929
class AvailabilityContext::Info {
3030
public:
3131
/// The introduction version.
32-
AvailabilityRange Range;
32+
AvailabilityRange PlatformRange;
3333

3434
/// A sorted collection of disjoint domains that are known to be
3535
/// unavailable in this context.
@@ -48,7 +48,7 @@ class AvailabilityContext::Info {
4848
/// restrictive than the current values. Returns true if any field was
4949
/// updated.
5050
bool constrainWith(const DeclAvailabilityConstraints &constraints,
51-
ASTContext &ctx);
51+
const ASTContext &ctx);
5252

5353
bool constrainUnavailability(
5454
const llvm::SmallVectorImpl<AvailabilityDomain> &domains);
@@ -63,7 +63,7 @@ class AvailabilityContext::Info {
6363
void Profile(llvm::FoldingSetNodeID &ID) const;
6464

6565
/// Returns true if all internal invariants are satisfied.
66-
bool verify(ASTContext &ctx) const;
66+
bool verify(const ASTContext &ctx) const;
6767
};
6868

6969
/// As an implementation detail, the values that make up an `Availability`
@@ -74,7 +74,7 @@ class AvailabilityContext::Storage final : public llvm::FoldingSetNode {
7474
public:
7575
Info info;
7676

77-
static const Storage *get(const Info &info, ASTContext &ctx);
77+
static const Storage *get(const Info &info, const ASTContext &ctx);
7878

7979
void Profile(llvm::FoldingSetNodeID &ID) const { info.Profile(ID); }
8080
};

lib/AST/ASTContext.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -5714,7 +5714,7 @@ SubstitutionMap::Storage *SubstitutionMap::Storage::get(
57145714
}
57155715

57165716
const AvailabilityContext::Storage *
5717-
AvailabilityContext::Storage::get(const Info &info, ASTContext &ctx) {
5717+
AvailabilityContext::Storage::get(const Info &info, const ASTContext &ctx) {
57185718
llvm::FoldingSetNodeID id;
57195719
info.Profile(id);
57205720

lib/AST/AvailabilityConstraint.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ AvailabilityConstraint::getRequiredNewerAvailabilityRange(
2828
switch (getReason()) {
2929
case Reason::UnconditionallyUnavailable:
3030
case Reason::Obsoleted:
31-
case Reason::IntroducedInLaterVersion:
31+
case Reason::UnavailableForDeployment:
3232
return std::nullopt;
33-
case Reason::IntroducedInLaterDynamicVersion:
33+
case Reason::PotentiallyUnavailable:
3434
return getAttr().getIntroducedRange(ctx);
3535
}
3636
}
@@ -60,12 +60,12 @@ static bool constraintIsStronger(const AvailabilityConstraint &lhs,
6060
return false;
6161

6262
case AvailabilityConstraint::Reason::Obsoleted:
63-
// Pick the earliest obsoleted version.
63+
// Pick the larger obsoleted range.
6464
return *lhs.getAttr().getObsoleted() < *rhs.getAttr().getObsoleted();
6565

66-
case AvailabilityConstraint::Reason::IntroducedInLaterVersion:
67-
case AvailabilityConstraint::Reason::IntroducedInLaterDynamicVersion:
68-
// Pick the latest introduced version.
66+
case AvailabilityConstraint::Reason::UnavailableForDeployment:
67+
case AvailabilityConstraint::Reason::PotentiallyUnavailable:
68+
// Pick the smaller introduced range.
6969
return *lhs.getAttr().getIntroduced() > *rhs.getAttr().getIntroduced();
7070
}
7171
}
@@ -159,10 +159,10 @@ getAvailabilityConstraintForAttr(const Decl *decl,
159159
// FIXME: [availability] Expand this to cover custom versioned domains
160160
if (attr.isPlatformSpecific()) {
161161
if (!context.getPlatformRange().isContainedIn(introducedRange))
162-
return AvailabilityConstraint::introducedInLaterDynamicVersion(attr);
162+
return AvailabilityConstraint::potentiallyUnavailable(attr);
163163
} else if (deploymentRange &&
164164
!deploymentRange->isContainedIn(introducedRange)) {
165-
return AvailabilityConstraint::introducedInLaterVersion(attr);
165+
return AvailabilityConstraint::unavailableForDeployment(attr);
166166
}
167167

168168
return std::nullopt;

lib/AST/AvailabilityContext.cpp

+21-18
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ static bool constrainRange(AvailabilityRange &existing,
4040

4141
bool AvailabilityContext::Info::constrainWith(const Info &other) {
4242
bool isConstrained = false;
43-
isConstrained |= constrainRange(Range, other.Range);
43+
isConstrained |= constrainRange(PlatformRange, other.PlatformRange);
4444
isConstrained |= constrainUnavailability(other.UnavailableDomains);
4545
isConstrained |= CONSTRAIN_BOOL(IsDeprecated, other.IsDeprecated);
4646

4747
return isConstrained;
4848
}
4949

5050
bool AvailabilityContext::Info::constrainWith(
51-
const DeclAvailabilityConstraints &constraints, ASTContext &ctx) {
51+
const DeclAvailabilityConstraints &constraints, const ASTContext &ctx) {
5252
bool isConstrained = false;
5353

5454
for (auto constraint : constraints) {
@@ -57,14 +57,15 @@ bool AvailabilityContext::Info::constrainWith(
5757
switch (constraint.getReason()) {
5858
case AvailabilityConstraint::Reason::UnconditionallyUnavailable:
5959
case AvailabilityConstraint::Reason::Obsoleted:
60-
case AvailabilityConstraint::Reason::IntroducedInLaterVersion:
60+
case AvailabilityConstraint::Reason::UnavailableForDeployment:
6161
isConstrained |= constrainUnavailability(domain);
6262
break;
63-
case AvailabilityConstraint::Reason::IntroducedInLaterDynamicVersion:
63+
case AvailabilityConstraint::Reason::PotentiallyUnavailable:
6464
// FIXME: [availability] Support versioning for other kinds of domains.
6565
DEBUG_ASSERT(domain.isPlatform());
6666
if (domain.isPlatform())
67-
isConstrained |= constrainRange(Range, attr.getIntroducedRange(ctx));
67+
isConstrained |=
68+
constrainRange(PlatformRange, attr.getIntroducedRange(ctx));
6869
break;
6970
}
7071
}
@@ -121,7 +122,7 @@ bool AvailabilityContext::Info::constrainUnavailability(
121122

122123
bool AvailabilityContext::Info::isContainedIn(const Info &other) const {
123124
// The available versions range be the same or smaller.
124-
if (!Range.isContainedIn(other.Range))
125+
if (!PlatformRange.isContainedIn(other.PlatformRange))
125126
return false;
126127

127128
// Every unavailable domain in the other context should be contained in some
@@ -147,15 +148,15 @@ bool AvailabilityContext::Info::isContainedIn(const Info &other) const {
147148
}
148149

149150
void AvailabilityContext::Info::Profile(llvm::FoldingSetNodeID &ID) const {
150-
Range.getRawVersionRange().Profile(ID);
151+
PlatformRange.getRawVersionRange().Profile(ID);
151152
ID.AddInteger(UnavailableDomains.size());
152153
for (auto domain : UnavailableDomains) {
153154
domain.Profile(ID);
154155
}
155156
ID.AddBoolean(IsDeprecated);
156157
}
157158

158-
bool AvailabilityContext::Info::verify(ASTContext &ctx) const {
159+
bool AvailabilityContext::Info::verify(const ASTContext &ctx) const {
159160
// Unavailable domains must be sorted to ensure folding set node lookups yield
160161
// consistent results.
161162
if (!llvm::is_sorted(UnavailableDomains,
@@ -167,24 +168,26 @@ bool AvailabilityContext::Info::verify(ASTContext &ctx) const {
167168

168169
AvailabilityContext
169170
AvailabilityContext::forPlatformRange(const AvailabilityRange &range,
170-
ASTContext &ctx) {
171+
const ASTContext &ctx) {
171172
Info info{range, /*UnavailableDomains*/ {},
172173
/*IsDeprecated*/ false};
173174
return AvailabilityContext(Storage::get(info, ctx));
174175
}
175176

176-
AvailabilityContext AvailabilityContext::forInliningTarget(ASTContext &ctx) {
177+
AvailabilityContext
178+
AvailabilityContext::forInliningTarget(const ASTContext &ctx) {
177179
return AvailabilityContext::forPlatformRange(
178180
AvailabilityRange::forInliningTarget(ctx), ctx);
179181
}
180182

181-
AvailabilityContext AvailabilityContext::forDeploymentTarget(ASTContext &ctx) {
183+
AvailabilityContext
184+
AvailabilityContext::forDeploymentTarget(const ASTContext &ctx) {
182185
return AvailabilityContext::forPlatformRange(
183186
AvailabilityRange::forDeploymentTarget(ctx), ctx);
184187
}
185188

186189
AvailabilityRange AvailabilityContext::getPlatformRange() const {
187-
return storage->info.Range;
190+
return storage->info.PlatformRange;
188191
}
189192

190193
bool AvailabilityContext::isUnavailable() const {
@@ -205,7 +208,7 @@ bool AvailabilityContext::isDeprecated() const {
205208
}
206209

207210
void AvailabilityContext::constrainWithContext(const AvailabilityContext &other,
208-
ASTContext &ctx) {
211+
const ASTContext &ctx) {
209212
bool isConstrained = false;
210213

211214
Info info{storage->info};
@@ -218,17 +221,17 @@ void AvailabilityContext::constrainWithContext(const AvailabilityContext &other,
218221
}
219222

220223
void AvailabilityContext::constrainWithPlatformRange(
221-
const AvailabilityRange &platformRange, ASTContext &ctx) {
224+
const AvailabilityRange &platformRange, const ASTContext &ctx) {
222225

223226
Info info{storage->info};
224-
if (!constrainRange(info.Range, platformRange))
227+
if (!constrainRange(info.PlatformRange, platformRange))
225228
return;
226229

227230
storage = Storage::get(info, ctx);
228231
}
229232

230233
void AvailabilityContext::constrainWithUnavailableDomain(
231-
AvailabilityDomain domain, ASTContext &ctx) {
234+
AvailabilityDomain domain, const ASTContext &ctx) {
232235
Info info{storage->info};
233236
if (!info.constrainUnavailability(domain))
234237
return;
@@ -251,7 +254,7 @@ void AvailabilityContext::constrainWithDeclAndPlatformRange(
251254
swift::getAvailabilityConstraintsForDecl(decl, *this, flags);
252255
isConstrained |= info.constrainWith(constraints, decl->getASTContext());
253256
isConstrained |= CONSTRAIN_BOOL(info.IsDeprecated, decl->isDeprecated());
254-
isConstrained |= constrainRange(info.Range, platformRange);
257+
isConstrained |= constrainRange(info.PlatformRange, platformRange);
255258

256259
if (!isConstrained)
257260
return;
@@ -289,6 +292,6 @@ void AvailabilityContext::print(llvm::raw_ostream &os) const {
289292

290293
void AvailabilityContext::dump() const { print(llvm::errs()); }
291294

292-
bool AvailabilityContext::verify(ASTContext &ctx) const {
295+
bool AvailabilityContext::verify(const ASTContext &ctx) const {
293296
return storage->info.verify(ctx);
294297
}

lib/Sema/TypeCheckAvailability.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -3007,9 +3007,9 @@ bool shouldHideDomainNameForConstraintDiagnostic(
30073007
case AvailabilityDomain::Kind::SwiftLanguage:
30083008
switch (constraint.getReason()) {
30093009
case AvailabilityConstraint::Reason::UnconditionallyUnavailable:
3010-
case AvailabilityConstraint::Reason::IntroducedInLaterVersion:
3010+
case AvailabilityConstraint::Reason::UnavailableForDeployment:
30113011
return false;
3012-
case AvailabilityConstraint::Reason::IntroducedInLaterDynamicVersion:
3012+
case AvailabilityConstraint::Reason::PotentiallyUnavailable:
30133013
case AvailabilityConstraint::Reason::Obsoleted:
30143014
return true;
30153015
}
@@ -3058,7 +3058,7 @@ bool diagnoseExplicitUnavailability(SourceLoc loc,
30583058
proto)
30593059
.highlight(attr.getParsedAttr()->getRange());
30603060
break;
3061-
case AvailabilityConstraint::Reason::IntroducedInLaterVersion:
3061+
case AvailabilityConstraint::Reason::UnavailableForDeployment:
30623062
diags.diagnose(ext, diag::conformance_availability_introduced_in_version,
30633063
type, proto, domain, *attr.getIntroduced());
30643064
break;
@@ -3068,7 +3068,7 @@ bool diagnoseExplicitUnavailability(SourceLoc loc,
30683068
domain, *attr.getObsoleted())
30693069
.highlight(attr.getParsedAttr()->getRange());
30703070
break;
3071-
case AvailabilityConstraint::Reason::IntroducedInLaterDynamicVersion:
3071+
case AvailabilityConstraint::Reason::PotentiallyUnavailable:
30723072
llvm_unreachable("unexpected constraint");
30733073
}
30743074
return true;
@@ -3478,7 +3478,7 @@ bool diagnoseExplicitUnavailability(
34783478
diags.diagnose(D, diag::availability_marked_unavailable, D)
34793479
.highlight(sourceRange);
34803480
break;
3481-
case AvailabilityConstraint::Reason::IntroducedInLaterVersion:
3481+
case AvailabilityConstraint::Reason::UnavailableForDeployment:
34823482
diags
34833483
.diagnose(D, diag::availability_introduced_in_version, D, domain,
34843484
*Attr.getIntroduced())
@@ -3490,7 +3490,7 @@ bool diagnoseExplicitUnavailability(
34903490
*Attr.getObsoleted())
34913491
.highlight(sourceRange);
34923492
break;
3493-
case AvailabilityConstraint::Reason::IntroducedInLaterDynamicVersion:
3493+
case AvailabilityConstraint::Reason::PotentiallyUnavailable:
34943494
llvm_unreachable("unexpected constraint");
34953495
break;
34963496
}

0 commit comments

Comments
 (0)