@@ -1953,10 +1953,9 @@ static void findAvailabilityFixItNodes(
1953
1953
1954
1954
// / Emit a diagnostic note and Fix-It to add an @available attribute
1955
1955
// / on the given declaration for the given version range.
1956
- static void
1957
- fixAvailabilityForDecl (SourceRange ReferenceRange, const Decl *D,
1958
- const AvailabilityRange &RequiredAvailability,
1959
- ASTContext &Context) {
1956
+ static void fixAvailabilityForDecl (
1957
+ SourceRange ReferenceRange, const Decl *D, AvailabilityDomain Domain,
1958
+ const AvailabilityRange &RequiredAvailability, ASTContext &Context) {
1960
1959
assert (D);
1961
1960
1962
1961
// Don't suggest adding an @available() to a declaration where we would
@@ -1989,11 +1988,10 @@ fixAvailabilityForDecl(SourceRange ReferenceRange, const Decl *D,
1989
1988
1990
1989
StringRef OriginalIndent =
1991
1990
Lexer::getIndentationForLine (Context.SourceMgr , InsertLoc);
1992
- PlatformKind Target = targetPlatform (Context.LangOpts );
1993
1991
1994
1992
D->diagnose (diag::availability_add_attribute, KindForDiagnostic)
1995
1993
.fixItInsert (InsertLoc, diag::insert_available_attr,
1996
- platformString (Target ),
1994
+ Domain. getNameForAttributePrinting ( ),
1997
1995
RequiredAvailability.getVersionString (), OriginalIndent);
1998
1996
}
1999
1997
@@ -2004,14 +2002,19 @@ fixAvailabilityForDecl(SourceRange ReferenceRange, const Decl *D,
2004
2002
// / condition to the required range.
2005
2003
static bool fixAvailabilityByNarrowingNearbyVersionCheck (
2006
2004
SourceRange ReferenceRange, const DeclContext *ReferenceDC,
2007
- const AvailabilityRange &RequiredAvailability, ASTContext &Context,
2008
- InFlightDiagnostic &Err) {
2005
+ AvailabilityDomain Domain, const AvailabilityRange &RequiredAvailability,
2006
+ ASTContext &Context, InFlightDiagnostic &Err) {
2007
+ // FIXME: [availability] Support fixing availability for non-platform domains
2008
+ if (!Domain.isPlatform ())
2009
+ return false ;
2010
+
2009
2011
const AvailabilityScope *scope = nullptr ;
2010
2012
(void )TypeChecker::overApproximateAvailabilityAtLocation (ReferenceRange.Start ,
2011
2013
ReferenceDC, &scope);
2012
2014
if (!scope)
2013
2015
return false ;
2014
2016
2017
+ // FIXME: [availability] Support fixing availability for versionless domains.
2015
2018
auto ExplicitAvailability = scope->getExplicitAvailabilityRange ();
2016
2019
if (ExplicitAvailability && !RequiredAvailability.isAlwaysAvailable () &&
2017
2020
scope->getReason () != AvailabilityScope::Reason::Root &&
@@ -2123,11 +2126,16 @@ static void fixAvailabilityByAddingVersionCheck(
2123
2126
// / requiting the given OS version range.
2124
2127
static void fixAvailability (SourceRange ReferenceRange,
2125
2128
const DeclContext *ReferenceDC,
2129
+ AvailabilityDomain Domain,
2126
2130
const AvailabilityRange &RequiredAvailability,
2127
2131
ASTContext &Context) {
2128
2132
if (ReferenceRange.isInvalid ())
2129
2133
return ;
2130
2134
2135
+ // FIXME: [availability] Support non-platform domains.
2136
+ if (!Domain.isPlatform ())
2137
+ return ;
2138
+
2131
2139
std::optional<ASTNode> NodeToWrapInVersionCheck;
2132
2140
const Decl *FoundMemberDecl = nullptr ;
2133
2141
const Decl *FoundTypeLevelDecl = nullptr ;
@@ -2145,12 +2153,12 @@ static void fixAvailability(SourceRange ReferenceRange,
2145
2153
2146
2154
// Suggest adding availability attributes.
2147
2155
if (FoundMemberDecl) {
2148
- fixAvailabilityForDecl (ReferenceRange, FoundMemberDecl,
2156
+ fixAvailabilityForDecl (ReferenceRange, FoundMemberDecl, Domain,
2149
2157
RequiredAvailability, Context);
2150
2158
}
2151
2159
2152
2160
if (FoundTypeLevelDecl) {
2153
- fixAvailabilityForDecl (ReferenceRange, FoundTypeLevelDecl,
2161
+ fixAvailabilityForDecl (ReferenceRange, FoundTypeLevelDecl, Domain,
2154
2162
RequiredAvailability, Context);
2155
2163
}
2156
2164
}
@@ -2160,19 +2168,19 @@ static void diagnosePotentialUnavailability(
2160
2168
llvm::function_ref<InFlightDiagnostic(AvailabilityDomain,
2161
2169
llvm::VersionTuple)>
2162
2170
Diagnose,
2163
- const DeclContext *ReferenceDC, const AvailabilityRange &Availability) {
2171
+ const DeclContext *ReferenceDC, AvailabilityDomain Domain,
2172
+ const AvailabilityRange &Availability) {
2164
2173
ASTContext &Context = ReferenceDC->getASTContext ();
2165
2174
2166
2175
{
2167
- auto Err = Diagnose (Context.getTargetAvailabilityDomain (),
2168
- Availability.getRawMinimumVersion ());
2176
+ auto Err = Diagnose (Domain, Availability.getRawMinimumVersion ());
2169
2177
2170
2178
// Direct a fixit to the error if an existing guard is nearly-correct
2171
2179
if (fixAvailabilityByNarrowingNearbyVersionCheck (
2172
- ReferenceRange, ReferenceDC, Availability, Context, Err))
2180
+ ReferenceRange, ReferenceDC, Domain, Availability, Context, Err))
2173
2181
return ;
2174
2182
}
2175
- fixAvailability (ReferenceRange, ReferenceDC, Availability, Context);
2183
+ fixAvailability (ReferenceRange, ReferenceDC, Domain, Availability, Context);
2176
2184
}
2177
2185
2178
2186
bool TypeChecker::checkAvailability (SourceRange ReferenceRange,
@@ -2185,12 +2193,16 @@ bool TypeChecker::checkAvailability(SourceRange ReferenceRange,
2185
2193
if (ctx.LangOpts .DisableAvailabilityChecking )
2186
2194
return false ;
2187
2195
2196
+ auto domain = ctx.getTargetAvailabilityDomain ();
2197
+ if (domain.isUniversal ())
2198
+ return false ;
2199
+
2188
2200
auto availabilityAtLocation =
2189
2201
TypeChecker::overApproximateAvailabilityAtLocation (ReferenceRange.Start ,
2190
2202
ReferenceDC);
2191
2203
if (!availabilityAtLocation.isContainedIn (RequiredAvailability)) {
2192
2204
diagnosePotentialUnavailability (ReferenceRange, Diagnose, ReferenceDC,
2193
- RequiredAvailability);
2205
+ domain, RequiredAvailability);
2194
2206
return true ;
2195
2207
}
2196
2208
@@ -2219,22 +2231,28 @@ void TypeChecker::checkConcurrencyAvailability(SourceRange ReferenceRange,
2219
2231
}
2220
2232
2221
2233
static bool
2222
- requiresDeploymentTargetOrEarlier (const AvailabilityRange &availability,
2234
+ requiresDeploymentTargetOrEarlier (AvailabilityDomain domain,
2235
+ const AvailabilityRange &availability,
2223
2236
ASTContext &ctx) {
2224
- auto deploymentTarget = AvailabilityRange::forDeploymentTarget (ctx);
2225
- return deploymentTarget.isContainedIn (availability);
2237
+ if (auto deploymentRange = domain.getDeploymentRange (ctx))
2238
+ return deploymentRange->isContainedIn (availability);
2239
+ return false ;
2226
2240
}
2227
2241
2228
2242
// / Returns the diagnostic to emit for the potentially unavailable decl and sets
2229
2243
// / \p IsError accordingly.
2230
2244
static Diagnostic getPotentialUnavailabilityDiagnostic (
2231
2245
const ValueDecl *D, const DeclContext *ReferenceDC,
2232
- const AvailabilityRange &Availability, bool WarnBeforeDeploymentTarget ,
2233
- bool &IsError) {
2246
+ AvailabilityDomain Domain, const AvailabilityRange &Availability,
2247
+ bool WarnBeforeDeploymentTarget, bool &IsError) {
2234
2248
ASTContext &Context = ReferenceDC->getASTContext ();
2235
- auto Domain = Context.getTargetAvailabilityDomain ();
2236
2249
2237
- if (requiresDeploymentTargetOrEarlier (Availability, Context)) {
2250
+ if (!Availability.hasMinimumVersion ()) {
2251
+ return Diagnostic (diag::availability_decl_only_version_newer, D, Domain,
2252
+ {});
2253
+ }
2254
+
2255
+ if (requiresDeploymentTargetOrEarlier (Domain, Availability, Context)) {
2238
2256
// The required OS version is at or before the deployment target so this
2239
2257
// diagnostic should indicate that the decl could be unavailable to clients
2240
2258
// of the module containing the reference.
@@ -2258,6 +2276,7 @@ static Diagnostic getPotentialUnavailabilityDiagnostic(
2258
2276
static bool
2259
2277
diagnosePotentialUnavailability (const ValueDecl *D, SourceRange ReferenceRange,
2260
2278
const DeclContext *ReferenceDC,
2279
+ AvailabilityDomain Domain,
2261
2280
const AvailabilityRange &Availability,
2262
2281
bool WarnBeforeDeploymentTarget = false ) {
2263
2282
ASTContext &Context = ReferenceDC->getASTContext ();
@@ -2267,26 +2286,26 @@ diagnosePotentialUnavailability(const ValueDecl *D, SourceRange ReferenceRange,
2267
2286
bool IsError;
2268
2287
{
2269
2288
auto Diag = Context.Diags .diagnose (
2270
- ReferenceRange.Start ,
2271
- getPotentialUnavailabilityDiagnostic (
2272
- D, ReferenceDC, Availability, WarnBeforeDeploymentTarget, IsError));
2289
+ ReferenceRange.Start , getPotentialUnavailabilityDiagnostic (
2290
+ D, ReferenceDC, Domain, Availability,
2291
+ WarnBeforeDeploymentTarget, IsError));
2273
2292
2274
2293
// Direct a fixit to the error if an existing guard is nearly-correct
2275
2294
if (fixAvailabilityByNarrowingNearbyVersionCheck (
2276
- ReferenceRange, ReferenceDC, Availability, Context, Diag))
2295
+ ReferenceRange, ReferenceDC, Domain, Availability, Context, Diag))
2277
2296
return IsError;
2278
2297
}
2279
2298
2280
- fixAvailability (ReferenceRange, ReferenceDC, Availability, Context);
2299
+ fixAvailability (ReferenceRange, ReferenceDC, Domain, Availability, Context);
2281
2300
return IsError;
2282
2301
}
2283
2302
2284
2303
// / Emits a diagnostic for a reference to a storage accessor that is
2285
2304
// / potentially unavailable.
2286
2305
static void diagnosePotentialAccessorUnavailability (
2287
2306
const AccessorDecl *Accessor, SourceRange ReferenceRange,
2288
- const DeclContext *ReferenceDC, const AvailabilityRange &Availability ,
2289
- bool ForInout) {
2307
+ const DeclContext *ReferenceDC, AvailabilityDomain Domain ,
2308
+ const AvailabilityRange &Availability, bool ForInout) {
2290
2309
ASTContext &Context = ReferenceDC->getASTContext ();
2291
2310
2292
2311
assert (Accessor->isGetterOrSetter ());
@@ -2301,11 +2320,11 @@ static void diagnosePotentialAccessorUnavailability(
2301
2320
2302
2321
// Direct a fixit to the error if an existing guard is nearly-correct
2303
2322
if (fixAvailabilityByNarrowingNearbyVersionCheck (
2304
- ReferenceRange, ReferenceDC, Availability, Context, Err))
2323
+ ReferenceRange, ReferenceDC, Domain, Availability, Context, Err))
2305
2324
return ;
2306
2325
}
2307
2326
2308
- fixAvailability (ReferenceRange, ReferenceDC, Availability, Context);
2327
+ fixAvailability (ReferenceRange, ReferenceDC, Domain, Availability, Context);
2309
2328
}
2310
2329
2311
2330
static DiagnosticBehavior
@@ -2329,11 +2348,10 @@ behaviorLimitForExplicitUnavailability(
2329
2348
2330
2349
// / Emits a diagnostic for a protocol conformance that is potentially
2331
2350
// / unavailable at the given source location.
2332
- static bool
2333
- diagnosePotentialUnavailability (const RootProtocolConformance *rootConf,
2334
- const ExtensionDecl *ext, SourceLoc loc,
2335
- const DeclContext *dc,
2336
- const AvailabilityRange &availability) {
2351
+ static bool diagnosePotentialUnavailability (
2352
+ const RootProtocolConformance *rootConf, const ExtensionDecl *ext,
2353
+ SourceLoc loc, const DeclContext *dc, AvailabilityDomain domain,
2354
+ const AvailabilityRange &availability) {
2337
2355
ASTContext &ctx = dc->getASTContext ();
2338
2356
if (ctx.LangOpts .DisableAvailabilityChecking )
2339
2357
return false ;
@@ -2343,7 +2361,7 @@ diagnosePotentialUnavailability(const RootProtocolConformance *rootConf,
2343
2361
auto proto = rootConf->getProtocol ()->getDeclaredInterfaceType ();
2344
2362
auto err = ctx.Diags .diagnose (
2345
2363
loc, diag::conformance_availability_only_version_newer, type, proto,
2346
- ctx. getTargetAvailabilityDomain () , availability.getRawMinimumVersion ());
2364
+ domain , availability.getRawMinimumVersion ());
2347
2365
2348
2366
auto behaviorLimit = behaviorLimitForExplicitUnavailability (rootConf, dc);
2349
2367
if (behaviorLimit >= DiagnosticBehavior::Warning)
@@ -2352,12 +2370,12 @@ diagnosePotentialUnavailability(const RootProtocolConformance *rootConf,
2352
2370
err.warnUntilSwiftVersion (6 );
2353
2371
2354
2372
// Direct a fixit to the error if an existing guard is nearly-correct
2355
- if (fixAvailabilityByNarrowingNearbyVersionCheck (loc, dc, availability, ctx ,
2356
- err))
2373
+ if (fixAvailabilityByNarrowingNearbyVersionCheck (loc, dc, domain ,
2374
+ availability, ctx, err))
2357
2375
return true ;
2358
2376
}
2359
2377
2360
- fixAvailability (loc, dc, availability, ctx);
2378
+ fixAvailability (loc, dc, domain, availability, ctx);
2361
2379
return true ;
2362
2380
}
2363
2381
@@ -4176,24 +4194,24 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
4176
4194
if (!constraint)
4177
4195
return false ;
4178
4196
4179
- auto requiredRange = constraint->getRequiredNewerAvailabilityRange (ctx);
4180
-
4181
4197
// Diagnose (and possibly signal) for potential unavailability
4198
+ auto domain = constraint->getDomain ();
4199
+ auto requiredRange = constraint->getPotentiallyUnavailableRange (ctx);
4182
4200
if (!requiredRange)
4183
4201
return false ;
4184
4202
4185
4203
if (Flags.contains (
4186
4204
DeclAvailabilityFlag::
4187
4205
AllowPotentiallyUnavailableAtOrBelowDeploymentTarget) &&
4188
- requiresDeploymentTargetOrEarlier (*requiredRange, ctx))
4206
+ requiresDeploymentTargetOrEarlier (domain, *requiredRange, ctx))
4189
4207
return false ;
4190
4208
4191
4209
if (accessor) {
4192
4210
bool forInout = Flags.contains (DeclAvailabilityFlag::ForInout);
4193
- diagnosePotentialAccessorUnavailability (accessor, R, DC, *requiredRange ,
4194
- forInout);
4211
+ diagnosePotentialAccessorUnavailability (accessor, R, DC, domain ,
4212
+ *requiredRange, forInout);
4195
4213
} else {
4196
- if (!diagnosePotentialUnavailability (D, R, DC, *requiredRange))
4214
+ if (!diagnosePotentialUnavailability (D, R, DC, domain, *requiredRange))
4197
4215
return false ;
4198
4216
}
4199
4217
@@ -4680,8 +4698,9 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
4680
4698
4681
4699
// Diagnose (and possibly signal) for potential unavailability
4682
4700
if (auto requiredRange =
4683
- constraint->getRequiredNewerAvailabilityRange (ctx)) {
4701
+ constraint->getPotentiallyUnavailableRange (ctx)) {
4684
4702
if (diagnosePotentialUnavailability (rootConf, ext, loc, DC,
4703
+ constraint->getDomain (),
4685
4704
*requiredRange)) {
4686
4705
maybeEmitAssociatedTypeNote ();
4687
4706
return true ;
0 commit comments