@@ -31,52 +31,96 @@ class ASTContext;
31
31
class AvailabilityContext ;
32
32
class Decl ;
33
33
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` .
36
36
class AvailabilityConstraint {
37
37
public:
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
+ // / }
39
100
// /
40
101
// / NOTE: The order of this enum matters. Reasons are defined in descending
41
102
// / priority order.
42
103
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,
80
124
};
81
125
82
126
private:
@@ -87,49 +131,42 @@ class AvailabilityConstraint {
87
131
88
132
public:
89
133
static AvailabilityConstraint
90
- unconditionallyUnavailable (SemanticAvailableAttr attr) {
91
- return AvailabilityConstraint (Reason::UnconditionallyUnavailable , attr);
134
+ unavailableUnconditionally (SemanticAvailableAttr attr) {
135
+ return AvailabilityConstraint (Reason::UnavailableUnconditionally , attr);
92
136
}
93
137
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);
96
141
}
97
142
98
143
static AvailabilityConstraint
99
- unavailableForDeployment (SemanticAvailableAttr attr) {
100
- return AvailabilityConstraint (Reason::UnavailableForDeployment , attr);
144
+ unavailableUnintroduced (SemanticAvailableAttr attr) {
145
+ return AvailabilityConstraint (Reason::UnavailableUnintroduced , attr);
101
146
}
102
147
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);
106
150
}
107
151
108
152
Reason getReason () const { return attrAndReason.getInt (); }
109
153
SemanticAvailableAttr getAttr () const {
110
154
return static_cast <SemanticAvailableAttr>(attrAndReason.getPointer ());
111
155
}
112
156
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 {
114
160
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 ;
121
167
}
122
168
}
123
169
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
-
133
170
// / Returns the domain that the constraint applies to.
134
171
AvailabilityDomain getDomain () const { return getAttr ().getDomain (); }
135
172
0 commit comments