@@ -1953,10 +1953,9 @@ static void findAvailabilityFixItNodes(
19531953
19541954// / Emit a diagnostic note and Fix-It to add an @available attribute
19551955// / 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) {
19601959 assert (D);
19611960
19621961 // Don't suggest adding an @available() to a declaration where we would
@@ -1989,11 +1988,10 @@ fixAvailabilityForDecl(SourceRange ReferenceRange, const Decl *D,
19891988
19901989 StringRef OriginalIndent =
19911990 Lexer::getIndentationForLine (Context.SourceMgr , InsertLoc);
1992- PlatformKind Target = targetPlatform (Context.LangOpts );
19931991
19941992 D->diagnose (diag::availability_add_attribute, KindForDiagnostic)
19951993 .fixItInsert (InsertLoc, diag::insert_available_attr,
1996- platformString (Target ),
1994+ Domain. getNameForAttributePrinting ( ),
19971995 RequiredAvailability.getVersionString (), OriginalIndent);
19981996}
19991997
@@ -2004,14 +2002,19 @@ fixAvailabilityForDecl(SourceRange ReferenceRange, const Decl *D,
20042002// / condition to the required range.
20052003static bool fixAvailabilityByNarrowingNearbyVersionCheck (
20062004 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+
20092011 const AvailabilityScope *scope = nullptr ;
20102012 (void )TypeChecker::overApproximateAvailabilityAtLocation (ReferenceRange.Start ,
20112013 ReferenceDC, &scope);
20122014 if (!scope)
20132015 return false ;
20142016
2017+ // FIXME: [availability] Support fixing availability for versionless domains.
20152018 auto ExplicitAvailability = scope->getExplicitAvailabilityRange ();
20162019 if (ExplicitAvailability && !RequiredAvailability.isAlwaysAvailable () &&
20172020 scope->getReason () != AvailabilityScope::Reason::Root &&
@@ -2123,11 +2126,16 @@ static void fixAvailabilityByAddingVersionCheck(
21232126// / requiting the given OS version range.
21242127static void fixAvailability (SourceRange ReferenceRange,
21252128 const DeclContext *ReferenceDC,
2129+ AvailabilityDomain Domain,
21262130 const AvailabilityRange &RequiredAvailability,
21272131 ASTContext &Context) {
21282132 if (ReferenceRange.isInvalid ())
21292133 return ;
21302134
2135+ // FIXME: [availability] Support non-platform domains.
2136+ if (!Domain.isPlatform ())
2137+ return ;
2138+
21312139 std::optional<ASTNode> NodeToWrapInVersionCheck;
21322140 const Decl *FoundMemberDecl = nullptr ;
21332141 const Decl *FoundTypeLevelDecl = nullptr ;
@@ -2145,12 +2153,12 @@ static void fixAvailability(SourceRange ReferenceRange,
21452153
21462154 // Suggest adding availability attributes.
21472155 if (FoundMemberDecl) {
2148- fixAvailabilityForDecl (ReferenceRange, FoundMemberDecl,
2156+ fixAvailabilityForDecl (ReferenceRange, FoundMemberDecl, Domain,
21492157 RequiredAvailability, Context);
21502158 }
21512159
21522160 if (FoundTypeLevelDecl) {
2153- fixAvailabilityForDecl (ReferenceRange, FoundTypeLevelDecl,
2161+ fixAvailabilityForDecl (ReferenceRange, FoundTypeLevelDecl, Domain,
21542162 RequiredAvailability, Context);
21552163 }
21562164}
@@ -2160,19 +2168,19 @@ static void diagnosePotentialUnavailability(
21602168 llvm::function_ref<InFlightDiagnostic(AvailabilityDomain,
21612169 llvm::VersionTuple)>
21622170 Diagnose,
2163- const DeclContext *ReferenceDC, const AvailabilityRange &Availability) {
2171+ const DeclContext *ReferenceDC, AvailabilityDomain Domain,
2172+ const AvailabilityRange &Availability) {
21642173 ASTContext &Context = ReferenceDC->getASTContext ();
21652174
21662175 {
2167- auto Err = Diagnose (Context.getTargetAvailabilityDomain (),
2168- Availability.getRawMinimumVersion ());
2176+ auto Err = Diagnose (Domain, Availability.getRawMinimumVersion ());
21692177
21702178 // Direct a fixit to the error if an existing guard is nearly-correct
21712179 if (fixAvailabilityByNarrowingNearbyVersionCheck (
2172- ReferenceRange, ReferenceDC, Availability, Context, Err))
2180+ ReferenceRange, ReferenceDC, Domain, Availability, Context, Err))
21732181 return ;
21742182 }
2175- fixAvailability (ReferenceRange, ReferenceDC, Availability, Context);
2183+ fixAvailability (ReferenceRange, ReferenceDC, Domain, Availability, Context);
21762184}
21772185
21782186bool TypeChecker::checkAvailability (SourceRange ReferenceRange,
@@ -2185,12 +2193,16 @@ bool TypeChecker::checkAvailability(SourceRange ReferenceRange,
21852193 if (ctx.LangOpts .DisableAvailabilityChecking )
21862194 return false ;
21872195
2196+ auto domain = ctx.getTargetAvailabilityDomain ();
2197+ if (domain.isUniversal ())
2198+ return false ;
2199+
21882200 auto availabilityAtLocation =
21892201 TypeChecker::overApproximateAvailabilityAtLocation (ReferenceRange.Start ,
21902202 ReferenceDC);
21912203 if (!availabilityAtLocation.isContainedIn (RequiredAvailability)) {
21922204 diagnosePotentialUnavailability (ReferenceRange, Diagnose, ReferenceDC,
2193- RequiredAvailability);
2205+ domain, RequiredAvailability);
21942206 return true ;
21952207 }
21962208
@@ -2219,22 +2231,28 @@ void TypeChecker::checkConcurrencyAvailability(SourceRange ReferenceRange,
22192231}
22202232
22212233static bool
2222- requiresDeploymentTargetOrEarlier (const AvailabilityRange &availability,
2234+ requiresDeploymentTargetOrEarlier (AvailabilityDomain domain,
2235+ const AvailabilityRange &availability,
22232236 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 ;
22262240}
22272241
22282242// / Returns the diagnostic to emit for the potentially unavailable decl and sets
22292243// / \p IsError accordingly.
22302244static Diagnostic getPotentialUnavailabilityDiagnostic (
22312245 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) {
22342248 ASTContext &Context = ReferenceDC->getASTContext ();
2235- auto Domain = Context.getTargetAvailabilityDomain ();
22362249
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)) {
22382256 // The required OS version is at or before the deployment target so this
22392257 // diagnostic should indicate that the decl could be unavailable to clients
22402258 // of the module containing the reference.
@@ -2258,6 +2276,7 @@ static Diagnostic getPotentialUnavailabilityDiagnostic(
22582276static bool
22592277diagnosePotentialUnavailability (const ValueDecl *D, SourceRange ReferenceRange,
22602278 const DeclContext *ReferenceDC,
2279+ AvailabilityDomain Domain,
22612280 const AvailabilityRange &Availability,
22622281 bool WarnBeforeDeploymentTarget = false ) {
22632282 ASTContext &Context = ReferenceDC->getASTContext ();
@@ -2267,26 +2286,26 @@ diagnosePotentialUnavailability(const ValueDecl *D, SourceRange ReferenceRange,
22672286 bool IsError;
22682287 {
22692288 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));
22732292
22742293 // Direct a fixit to the error if an existing guard is nearly-correct
22752294 if (fixAvailabilityByNarrowingNearbyVersionCheck (
2276- ReferenceRange, ReferenceDC, Availability, Context, Diag))
2295+ ReferenceRange, ReferenceDC, Domain, Availability, Context, Diag))
22772296 return IsError;
22782297 }
22792298
2280- fixAvailability (ReferenceRange, ReferenceDC, Availability, Context);
2299+ fixAvailability (ReferenceRange, ReferenceDC, Domain, Availability, Context);
22812300 return IsError;
22822301}
22832302
22842303// / Emits a diagnostic for a reference to a storage accessor that is
22852304// / potentially unavailable.
22862305static void diagnosePotentialAccessorUnavailability (
22872306 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) {
22902309 ASTContext &Context = ReferenceDC->getASTContext ();
22912310
22922311 assert (Accessor->isGetterOrSetter ());
@@ -2301,11 +2320,11 @@ static void diagnosePotentialAccessorUnavailability(
23012320
23022321 // Direct a fixit to the error if an existing guard is nearly-correct
23032322 if (fixAvailabilityByNarrowingNearbyVersionCheck (
2304- ReferenceRange, ReferenceDC, Availability, Context, Err))
2323+ ReferenceRange, ReferenceDC, Domain, Availability, Context, Err))
23052324 return ;
23062325 }
23072326
2308- fixAvailability (ReferenceRange, ReferenceDC, Availability, Context);
2327+ fixAvailability (ReferenceRange, ReferenceDC, Domain, Availability, Context);
23092328}
23102329
23112330static DiagnosticBehavior
@@ -2329,11 +2348,10 @@ behaviorLimitForExplicitUnavailability(
23292348
23302349// / Emits a diagnostic for a protocol conformance that is potentially
23312350// / 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) {
23372355 ASTContext &ctx = dc->getASTContext ();
23382356 if (ctx.LangOpts .DisableAvailabilityChecking )
23392357 return false ;
@@ -2343,7 +2361,7 @@ diagnosePotentialUnavailability(const RootProtocolConformance *rootConf,
23432361 auto proto = rootConf->getProtocol ()->getDeclaredInterfaceType ();
23442362 auto err = ctx.Diags .diagnose (
23452363 loc, diag::conformance_availability_only_version_newer, type, proto,
2346- ctx. getTargetAvailabilityDomain () , availability.getRawMinimumVersion ());
2364+ domain , availability.getRawMinimumVersion ());
23472365
23482366 auto behaviorLimit = behaviorLimitForExplicitUnavailability (rootConf, dc);
23492367 if (behaviorLimit >= DiagnosticBehavior::Warning)
@@ -2352,12 +2370,12 @@ diagnosePotentialUnavailability(const RootProtocolConformance *rootConf,
23522370 err.warnUntilSwiftVersion (6 );
23532371
23542372 // 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))
23572375 return true ;
23582376 }
23592377
2360- fixAvailability (loc, dc, availability, ctx);
2378+ fixAvailability (loc, dc, domain, availability, ctx);
23612379 return true ;
23622380}
23632381
@@ -4176,24 +4194,24 @@ bool swift::diagnoseDeclAvailability(const ValueDecl *D, SourceRange R,
41764194 if (!constraint)
41774195 return false ;
41784196
4179- auto requiredRange = constraint->getRequiredNewerAvailabilityRange (ctx);
4180-
41814197 // Diagnose (and possibly signal) for potential unavailability
4198+ auto domain = constraint->getDomain ();
4199+ auto requiredRange = constraint->getPotentiallyUnavailableRange (ctx);
41824200 if (!requiredRange)
41834201 return false ;
41844202
41854203 if (Flags.contains (
41864204 DeclAvailabilityFlag::
41874205 AllowPotentiallyUnavailableAtOrBelowDeploymentTarget) &&
4188- requiresDeploymentTargetOrEarlier (*requiredRange, ctx))
4206+ requiresDeploymentTargetOrEarlier (domain, *requiredRange, ctx))
41894207 return false ;
41904208
41914209 if (accessor) {
41924210 bool forInout = Flags.contains (DeclAvailabilityFlag::ForInout);
4193- diagnosePotentialAccessorUnavailability (accessor, R, DC, *requiredRange ,
4194- forInout);
4211+ diagnosePotentialAccessorUnavailability (accessor, R, DC, domain ,
4212+ *requiredRange, forInout);
41954213 } else {
4196- if (!diagnosePotentialUnavailability (D, R, DC, *requiredRange))
4214+ if (!diagnosePotentialUnavailability (D, R, DC, domain, *requiredRange))
41974215 return false ;
41984216 }
41994217
@@ -4680,8 +4698,9 @@ swift::diagnoseConformanceAvailability(SourceLoc loc,
46804698
46814699 // Diagnose (and possibly signal) for potential unavailability
46824700 if (auto requiredRange =
4683- constraint->getRequiredNewerAvailabilityRange (ctx)) {
4701+ constraint->getPotentiallyUnavailableRange (ctx)) {
46844702 if (diagnosePotentialUnavailability (rootConf, ext, loc, DC,
4703+ constraint->getDomain (),
46854704 *requiredRange)) {
46864705 maybeEmitAssociatedTypeNote ();
46874706 return true ;
0 commit comments