@@ -113,25 +113,59 @@ DeclAvailabilityConstraints::getPrimaryConstraint() const {
113
113
return result;
114
114
}
115
115
116
+ static bool canIgnoreConstraintInUnavailableContexts (
117
+ const Decl *decl, const AvailabilityConstraint &constraint) {
118
+ auto domain = constraint.getDomain ();
119
+
120
+ switch (constraint.getReason ()) {
121
+ case AvailabilityConstraint::Reason::UnconditionallyUnavailable:
122
+ // Always reject uses of universally unavailable declarations, regardless
123
+ // of context, since there are no possible compilation configurations in
124
+ // which they are available. However, make an exception for types and
125
+ // conformances, which can sometimes be awkward to avoid references to.
126
+ if (!isa<TypeDecl>(decl) && !isa<ExtensionDecl>(decl)) {
127
+ if (domain.isUniversal () || domain.isSwiftLanguage ())
128
+ return false ;
129
+ }
130
+ return true ;
131
+
132
+ case AvailabilityConstraint::Reason::PotentiallyUnavailable:
133
+ switch (domain.getKind ()) {
134
+ case AvailabilityDomain::Kind::Universal:
135
+ case AvailabilityDomain::Kind::SwiftLanguage:
136
+ case AvailabilityDomain::Kind::PackageDescription:
137
+ case AvailabilityDomain::Kind::Embedded:
138
+ case AvailabilityDomain::Kind::Custom:
139
+ return false ;
140
+ case AvailabilityDomain::Kind::Platform:
141
+ // Platform availability only applies to the target triple that the
142
+ // binary is being compiled for. Since the same declaration can be
143
+ // potentially unavailable from a given context when compiling for one
144
+ // platform, but available from that context when compiling for a
145
+ // different platform, it is overly strict to enforce potential platform
146
+ // unavailability constraints in contexts that are unavailable to that
147
+ // platform.
148
+ return true ;
149
+ }
150
+ return constraint.getDomain ().isPlatform ();
151
+
152
+ case AvailabilityConstraint::Reason::Obsoleted:
153
+ case AvailabilityConstraint::Reason::UnavailableForDeployment:
154
+ return false ;
155
+ }
156
+ }
157
+
116
158
static bool
117
- isInsideCompatibleUnavailableDeclaration (const Decl *decl,
118
- const SemanticAvailableAttr &attr ,
119
- const AvailabilityContext &context) {
159
+ shouldIgnoreConstraintInContext (const Decl *decl,
160
+ const AvailabilityConstraint &constraint ,
161
+ const AvailabilityContext &context) {
120
162
if (!context.isUnavailable ())
121
163
return false ;
122
164
123
- if (!attr. isUnconditionallyUnavailable ( ))
165
+ if (!canIgnoreConstraintInUnavailableContexts (decl, constraint ))
124
166
return false ;
125
167
126
- // Refuse calling universally unavailable functions from unavailable code,
127
- // but allow the use of types.
128
- auto domain = attr.getDomain ();
129
- if (!isa<TypeDecl>(decl) && !isa<ExtensionDecl>(decl)) {
130
- if (domain.isUniversal () || domain.isSwiftLanguage ())
131
- return false ;
132
- }
133
-
134
- return context.containsUnavailableDomain (domain);
168
+ return context.containsUnavailableDomain (constraint.getDomain ());
135
169
}
136
170
137
171
// / Returns the `AvailabilityConstraint` that describes how \p attr restricts
@@ -218,8 +252,7 @@ static void getAvailabilityConstraintsForDecl(
218
252
// declaration is unconditionally unavailable in a domain for which
219
253
// the context is already unavailable.
220
254
llvm::erase_if (constraints, [&](const AvailabilityConstraint &constraint) {
221
- return isInsideCompatibleUnavailableDeclaration (decl, constraint.getAttr (),
222
- context);
255
+ return shouldIgnoreConstraintInContext (decl, constraint, context);
223
256
});
224
257
}
225
258
0 commit comments