@@ -31,52 +31,96 @@ class ASTContext;
3131class AvailabilityContext ;
3232class Decl ;
3333
34- // / Represents the reason a declaration could be considered unavailable in a
35- // / certain context .
34+ // / Represents the reason a declaration is considered not available in a
35+ // / specific `AvailabilityContext` .
3636class AvailabilityConstraint {
3737public:
38- // / The reason that the availability constraint is unsatisfied.
38+ // / The reason that a declaration is not available in a context. Broadly, the
39+ // / declaration may either be "unintroduced" or "unavailable" depending on its
40+ // / `@available` attributes. A declaration that is unintroduced can become
41+ // / available if availability constraints are added to the context. For
42+ // / unavailable declarations, on the other hand, either changing the
43+ // / deployment target or making the context itself unavailable are necessary
44+ // / to satisfy the constraint.
45+ // /
46+ // / For example, take the following declaration `f()`:
47+ // /
48+ // / @available(macOS, introduced: 11.0, obsoleted: 14.0)
49+ // / func f() { ... }
50+ // /
51+ // / In contexts that may run on earlier OSes, references to `f()` yield
52+ // / an `Unintroduced` constraint:
53+ // /
54+ // / @available(macOS 10.15, *)
55+ // / func g() {
56+ // / f() // error: 'f()' is only available in macOS 11.0 or newer
57+ // / }
58+ // /
59+ // / macOS ... 11.0 14.0 ...
60+ // / f() |----------------[=======================)-----------------|
61+ // / g() |-----------[==============================================)
62+ // / ^
63+ // / Unintroduced
64+ // /
65+ // / On the other hand, in contexts where deployment target is high enough to
66+ // / make `f()` obsolete, references to it yield an `UnavailableObsolete`
67+ // / constraint:
68+ // /
69+ // / // compiled with -target arm64-apple-macos14
70+ // / func h() {
71+ // / f() // error: 'f()' is unavailable in macOS
72+ // / }
73+ // /
74+ // / macOS ... 11.0 14.0 ...
75+ // / f() |----------------[=======================)-----------------|
76+ // / h() |----------------------------------------[=================)
77+ // / ^
78+ // / UnavailableObsolete
79+ // /
80+ // / References to declarations that are unavailable in all versions of a
81+ // / domain generate `UnavailableUnconditional` constraints unless the context
82+ // / is also unavailable under the same conditions:
83+ // /
84+ // / @available(macOS, unavailable)
85+ // / func foo() { ... }
86+ // /
87+ // / func bar() {
88+ // / foo() // error: 'foo()' is unavailable in macOS
89+ // / }
90+ // /
91+ // / @available(macOS, unavailable)
92+ // / func baz() {
93+ // / foo() // OK
94+ // / }
95+ // /
96+ // / @available(*, unavailable)
97+ // / func qux() {
98+ // / foo() // also OK
99+ // / }
39100 // /
40101 // / NOTE: The order of this enum matters. Reasons are defined in descending
41102 // / priority order.
42103 enum class Reason {
43- // / The declaration is referenced in a context in which it is generally
44- // / unavailable. For example, a reference to a declaration that is
45- // / unavailable on macOS from a context that may execute on macOS has this
46- // / constraint.
47- UnconditionallyUnavailable,
48-
49- // / The declaration is referenced in a context in which it is considered
50- // / obsolete. For example, a reference to a declaration that is obsolete in
51- // / macOS 13 from a context that may execute on macOS 13 or later has this
52- // / constraint.
53- Obsoleted,
54-
55- // / The declaration is not available in the deployment configuration
56- // / specified for this compilation. For example, the declaration might only
57- // / be introduced in the Swift 6 language mode while the module is being
58- // / compiled in the Swift 5 language mode. These availability constraints
59- // / cannot be satisfied by adding constraining contextual availability using
60- // / `@available` attributes or `if #available` queries.
61- UnavailableForDeployment,
62-
63- // / The declaration is referenced in a context that does not have adequate
64- // / availability constraints. For example, a reference to a declaration that
65- // / was introduced in macOS 13 from a context that may execute on earlier
66- // / versions of macOS cannot satisfy this constraint. The constraint
67- // / can be satisfied, though, by introducing an `@available` attribute or an
68- // / `if #available(...)` query.
69- PotentiallyUnavailable,
70- };
71-
72- // / Classifies constraints into different high level categories.
73- enum class Kind {
74- // / There are no contexts in which the declaration would be available.
75- Unavailable,
76-
77- // / There are some contexts in which the declaration would be available if
78- // / additional constraints were added.
79- PotentiallyAvailable,
104+ // / The declaration is unconditionally unavailable, e.g. because of
105+ // / `@available(macOS, unavailable)`.
106+ UnavailableUnconditionally,
107+
108+ // / The declaration is obsolete, e.g. because of
109+ // / `@available(macOS, obsolete: 14.0)` in a program with a deployment
110+ // / target of `macOS 14` or later.
111+ UnavailableObsolete,
112+
113+ // / The declaration is only available for later deployment configurations,
114+ // / e.g. because of `@available(swift 6)` in a program compiled with
115+ // / `-swift-version 5`.
116+ UnavailableUnintroduced,
117+
118+ // / The declaration has not yet been introduced, e.g. because of
119+ // / `@available(macOS 14, *)` in a context that may run on macOS 13 or
120+ // / later. The constraint may be satisfied adding an `@available` attribute
121+ // / or an `if #available(...)` query with sufficient introduction
122+ // / constraints to the context.
123+ Unintroduced,
80124 };
81125
82126private:
@@ -87,49 +131,42 @@ class AvailabilityConstraint {
87131
88132public:
89133 static AvailabilityConstraint
90- unconditionallyUnavailable (SemanticAvailableAttr attr) {
91- return AvailabilityConstraint (Reason::UnconditionallyUnavailable , attr);
134+ unavailableUnconditionally (SemanticAvailableAttr attr) {
135+ return AvailabilityConstraint (Reason::UnavailableUnconditionally , attr);
92136 }
93137
94- static AvailabilityConstraint obsoleted (SemanticAvailableAttr attr) {
95- return AvailabilityConstraint (Reason::Obsoleted, attr);
138+ static AvailabilityConstraint
139+ unavailableObsolete (SemanticAvailableAttr attr) {
140+ return AvailabilityConstraint (Reason::UnavailableObsolete, attr);
96141 }
97142
98143 static AvailabilityConstraint
99- unavailableForDeployment (SemanticAvailableAttr attr) {
100- return AvailabilityConstraint (Reason::UnavailableForDeployment , attr);
144+ unavailableUnintroduced (SemanticAvailableAttr attr) {
145+ return AvailabilityConstraint (Reason::UnavailableUnintroduced , attr);
101146 }
102147
103- static AvailabilityConstraint
104- potentiallyUnavailable (SemanticAvailableAttr attr) {
105- return AvailabilityConstraint (Reason::PotentiallyUnavailable, attr);
148+ static AvailabilityConstraint unintroduced (SemanticAvailableAttr attr) {
149+ return AvailabilityConstraint (Reason::Unintroduced, attr);
106150 }
107151
108152 Reason getReason () const { return attrAndReason.getInt (); }
109153 SemanticAvailableAttr getAttr () const {
110154 return static_cast <SemanticAvailableAttr>(attrAndReason.getPointer ());
111155 }
112156
113- Kind getKind () const {
157+ // / Returns true if the constraint cannot be satisfied using a runtime
158+ // / availability query (`if #available(...)`).
159+ bool isUnavailable () const {
114160 switch (getReason ()) {
115- case Reason::UnconditionallyUnavailable :
116- case Reason::Obsoleted :
117- case Reason::UnavailableForDeployment :
118- return Kind::Unavailable ;
119- case Reason::PotentiallyUnavailable :
120- return Kind::PotentiallyAvailable ;
161+ case Reason::UnavailableUnconditionally :
162+ case Reason::UnavailableObsolete :
163+ case Reason::UnavailableUnintroduced :
164+ return true ;
165+ case Reason::Unintroduced :
166+ return false ;
121167 }
122168 }
123169
124- // / Returns true if the constraint cannot be satisfied at runtime.
125- bool isUnavailable () const { return getKind () == Kind::Unavailable; }
126-
127- // / Returns true if the constraint is unsatisfied but could be satisfied at
128- // / runtime in a more constrained context.
129- bool isPotentiallyAvailable () const {
130- return getKind () == Kind::PotentiallyAvailable;
131- }
132-
133170 // / Returns the domain that the constraint applies to.
134171 AvailabilityDomain getDomain () const { return getAttr ().getDomain (); }
135172
0 commit comments