@@ -112,6 +112,7 @@ AvailabilityDomain::builtinDomainForString(StringRef string,
112112 .Case (" *" , AvailabilityDomain::forUniversal ())
113113 .Case (" swift" , AvailabilityDomain::forSwiftLanguageMode ())
114114 .Case (" SwiftLanguageMode" , AvailabilityDomain::forSwiftLanguageMode ())
115+ .Case (" Swift" , AvailabilityDomain::forSwiftRuntime ())
115116 .Case (" _PackageDescription" ,
116117 AvailabilityDomain::forPackageDescription ())
117118 .Default (std::nullopt );
@@ -131,6 +132,7 @@ bool AvailabilityDomain::isVersioned() const {
131132 case Kind::Embedded:
132133 return false ;
133134 case Kind::SwiftLanguageMode:
135+ case Kind::SwiftRuntime:
134136 case Kind::PackageDescription:
135137 case Kind::Platform:
136138 return true ;
@@ -151,6 +153,12 @@ bool AvailabilityDomain::isVersionValid(
151153 case Kind::SwiftLanguageMode:
152154 case Kind::PackageDescription:
153155 return true ;
156+ case Kind::SwiftRuntime:
157+ // Swift 5.0 is the first ABI stable Swift runtime version.
158+ if (version.getMajor () < 5 )
159+ return false ;
160+ return true ;
161+
154162 case Kind::Platform:
155163 if (auto osType = tripleOSTypeForPlatform (getPlatformKind ()))
156164 return llvm::Triple::isValidVersionForOS (*osType, version);
@@ -167,6 +175,7 @@ bool AvailabilityDomain::supportsContextRefinement() const {
167175 case Kind::SwiftLanguageMode:
168176 case Kind::PackageDescription:
169177 return false ;
178+ case Kind::SwiftRuntime:
170179 case Kind::Platform:
171180 case Kind::Custom:
172181 return true ;
@@ -180,6 +189,7 @@ bool AvailabilityDomain::supportsQueries() const {
180189 case Kind::SwiftLanguageMode:
181190 case Kind::PackageDescription:
182191 return false ;
192+ case Kind::SwiftRuntime:
183193 case Kind::Platform:
184194 case Kind::Custom:
185195 return true ;
@@ -194,6 +204,8 @@ bool AvailabilityDomain::isActive(const ASTContext &ctx,
194204 case Kind::PackageDescription:
195205 case Kind::Embedded:
196206 return true ;
207+ case Kind::SwiftRuntime:
208+ return ctx.LangOpts .hasFeature (Feature::SwiftRuntimeAvailability);
197209 case Kind::Platform:
198210 return isPlatformActive (getPlatformKind (), ctx.LangOpts , forTargetVariant);
199211 case Kind::Custom:
@@ -211,6 +223,24 @@ bool AvailabilityDomain::isActivePlatform(const ASTContext &ctx,
211223 return isActive (ctx, forTargetVariant);
212224}
213225
226+ bool AvailabilityDomain::mustBeSpecifiedAlone () const {
227+ switch (getKind ()) {
228+ case Kind::Universal:
229+ case Kind::SwiftLanguageMode:
230+ case Kind::PackageDescription:
231+ case Kind::Embedded:
232+ case Kind::Custom:
233+ return true ;
234+ case Kind::SwiftRuntime:
235+ case Kind::Platform:
236+ // Platform and Swift runtime availability specifications can appear
237+ // together, e.g. `@available(Swift 6, macOS 15, iOS 18, *)`.
238+ // If there are ever multiple disjoint groups of domains that may be
239+ // specified together in the future, this will need to be re-designed.
240+ return false ;
241+ }
242+ }
243+
214244static std::optional<llvm::VersionTuple>
215245getDeploymentVersion (const AvailabilityDomain &domain, const ASTContext &ctx) {
216246 switch (domain.getKind ()) {
@@ -222,6 +252,10 @@ getDeploymentVersion(const AvailabilityDomain &domain, const ASTContext &ctx) {
222252 return ctx.LangOpts .EffectiveLanguageVersion ;
223253 case AvailabilityDomain::Kind::PackageDescription:
224254 return ctx.LangOpts .PackageDescriptionVersion ;
255+ case AvailabilityDomain::Kind::SwiftRuntime:
256+ if (!ctx.LangOpts .hasFeature (Feature::SwiftRuntimeAvailability))
257+ return std::nullopt ;
258+ return ctx.LangOpts .MinSwiftRuntimeVersion ;
225259 case AvailabilityDomain::Kind::Platform:
226260 if (domain.isActive (ctx))
227261 return ctx.LangOpts .getMinPlatformVersion ();
@@ -256,6 +290,9 @@ llvm::StringRef AvailabilityDomain::getNameForDiagnostics() const {
256290 case Kind::Universal:
257291 return " *" ;
258292 case Kind::SwiftLanguageMode:
293+ // FIXME: [runtime availability] Render language mode diags differently.
294+ return " Swift" ;
295+ case Kind::SwiftRuntime:
259296 return " Swift" ;
260297 case Kind::PackageDescription:
261298 return " PackageDescription" ;
@@ -274,6 +311,8 @@ llvm::StringRef AvailabilityDomain::getNameForAttributePrinting() const {
274311 return " *" ;
275312 case Kind::SwiftLanguageMode:
276313 return " swift" ;
314+ case Kind::SwiftRuntime:
315+ return " Swift" ;
277316 case Kind::PackageDescription:
278317 return " _PackageDescription" ;
279318 case Kind::Embedded:
@@ -308,6 +347,8 @@ bool AvailabilityDomain::contains(const AvailabilityDomain &other) const {
308347 case Kind::Embedded:
309348 case Kind::Custom:
310349 return other == *this ;
350+ case Kind::SwiftRuntime:
351+ return other.isPlatform () || other == *this ;
311352 case Kind::Platform:
312353 if (getPlatformKind () == other.getPlatformKind ())
313354 return true ;
@@ -321,6 +362,7 @@ bool AvailabilityDomain::isRoot() const {
321362 case AvailabilityDomain::Kind::Universal:
322363 case AvailabilityDomain::Kind::Embedded:
323364 case AvailabilityDomain::Kind::SwiftLanguageMode:
365+ case AvailabilityDomain::Kind::SwiftRuntime:
324366 case AvailabilityDomain::Kind::PackageDescription:
325367 return true ;
326368 case AvailabilityDomain::Kind::Platform:
@@ -406,6 +448,7 @@ AvailabilityDomain AvailabilityDomain::copy(ASTContext &ctx) const {
406448 switch (getKind ()) {
407449 case Kind::Universal:
408450 case Kind::SwiftLanguageMode:
451+ case Kind::SwiftRuntime:
409452 case Kind::PackageDescription:
410453 case Kind::Embedded:
411454 case Kind::Platform:
@@ -428,6 +471,7 @@ bool StableAvailabilityDomainComparator::operator()(
428471 switch (lhsKind) {
429472 case AvailabilityDomain::Kind::Universal:
430473 case AvailabilityDomain::Kind::SwiftLanguageMode:
474+ case AvailabilityDomain::Kind::SwiftRuntime:
431475 case AvailabilityDomain::Kind::PackageDescription:
432476 case AvailabilityDomain::Kind::Embedded:
433477 return false ;
@@ -504,31 +548,41 @@ AvailabilityDomainOrIdentifier::lookUpInDeclContext(
504548 return std::nullopt ;
505549 }
506550
507- if (!declContext->isInSwiftinterface ()) {
508- if (domain->isCustom () && !hasCustomAvailability) {
509- diags.diagnose (loc, diag::availability_domain_requires_feature, *domain,
510- " CustomAvailability" );
511- return std::nullopt ;
551+ // The remaining diagnostics are suppressed in .swiftinterfaces.
552+ if (declContext->isInSwiftinterface ())
553+ return domain;
554+
555+ // Use of custom domains requires the 'CustomAvailability' feature.
556+ if (domain->isCustom () && !hasCustomAvailability) {
557+ diags.diagnose (loc, diag::availability_domain_requires_feature, *domain,
558+ " CustomAvailability" );
559+ return std::nullopt ;
560+ }
561+
562+ // Use of the 'Swift' domain requires the 'SwiftRuntimeAvailability' feature.
563+ if (!hasSwiftRuntimeAvailability && domain->isSwiftRuntime ()) {
564+ diags.diagnose (loc, diag::availability_domain_requires_feature, *domain,
565+ " SwiftRuntimeAvailability" );
566+ return std::nullopt ;
567+ }
568+
569+ if (domain->isSwiftLanguageMode ()) {
570+ // When the 'SwiftRuntimeAvailability' feature is enabled, the 'swift'
571+ // domain spelling is deprecated in favor of 'SwiftLanguageMode'.
572+ if (hasSwiftRuntimeAvailability && identifier.str () == " swift" ) {
573+ diags
574+ .diagnose (loc, diag::availability_domain_renamed, identifier,
575+ " SwiftLanguageMode" )
576+ .fixItReplace (SourceRange (loc), " SwiftLanguageMode" );
512577 }
513578
514- if (domain->isSwiftLanguageMode ()) {
515- // 'swift' -> 'SwiftLanguageMode'
516- if (hasSwiftRuntimeAvailability && identifier.str () == " swift" ) {
517- diags
518- .diagnose (loc, diag::availability_domain_renamed, identifier,
519- " SwiftLanguageMode" )
520- .fixItReplace (SourceRange (loc), " SwiftLanguageMode" );
521- }
522-
523- if (!hasSwiftRuntimeAvailability &&
524- identifier.str () == " SwiftLanguageMode" ) {
525- // This diagnostic ("Swift requires '-enable-experimental-feature
526- // SwiftRuntimeAvailability'") is confusing but it's also temporary,
527- // assuming the experimental feature becomes official.
528- diags.diagnose (loc, diag::availability_domain_requires_feature, *domain,
529- " SwiftRuntimeAvailability" );
530- return std::nullopt ;
531- }
579+ // Use of the 'SwiftLanguageMode' domain spelling requires the
580+ // 'SwiftRuntimeAvailability' feature.
581+ if (!hasSwiftRuntimeAvailability &&
582+ identifier.str () == " SwiftLanguageMode" ) {
583+ diags.diagnose (loc, diag::availability_domain_requires_feature, *domain,
584+ " SwiftRuntimeAvailability" );
585+ return std::nullopt ;
532586 }
533587 }
534588
0 commit comments