AST: Introduce the SwiftLanguageMode availability domain spelling.

Require `-enable-experimental-feature SwiftRuntimeAvailability` to use this new
spelling.
This commit is contained in:
Allan Shortlidge
2025-10-07 09:50:39 -07:00
parent 4e9a883824
commit 2d8465b043
8 changed files with 69 additions and 17 deletions

View File

@@ -6986,6 +6986,12 @@ WARNING(availability_unsupported_version_number, none,
WARNING(availability_invalid_version_number_for_domain, none,
"'%0' is not a valid version number for %1",
(llvm::VersionTuple, AvailabilityDomain))
WARNING(availability_domain_renamed, none,
"%0 has been renamed to '%1'",
(Identifier, StringRef))
ERROR(availability_domain_requires_feature, none,
"%0 requires '-enable-experimental-feature %1'",
(AvailabilityDomain, StringRef))
WARNING(attr_availability_expected_deprecated_version, none,
"expected version number with 'deprecated' in '%0' attribute for %1",
@@ -6996,9 +7002,6 @@ WARNING(attr_availability_cannot_be_used_for_domain, none,
WARNING(attr_availability_expected_version_spec, none,
"expected 'introduced', 'deprecated', or 'obsoleted' in '%0' attribute "
"for %1", (const DeclAttribute, AvailabilityDomain))
ERROR(attr_availability_requires_custom_availability, none,
"%0 requires '-enable-experimental-feature CustomAvailability'",
(AvailabilityDomain))
ERROR(attr_availability_domain_access, none,
"availability domain '%0' is "
"%select{private|fileprivate|internal|package|%error|%error}1 "

View File

@@ -556,6 +556,9 @@ EXPERIMENTAL_FEATURE(BorrowAndMutateAccessors, false)
/// Allow use of @inline(always) attribute
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(InlineAlways, false)
/// Allow use of 'Swift' (Swift runtime version) in @available attributes
EXPERIMENTAL_FEATURE(SwiftRuntimeAvailability, true)
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
#undef EXPERIMENTAL_FEATURE
#undef UPCOMING_FEATURE

View File

@@ -107,12 +107,14 @@ AvailabilityDomain::builtinDomainForString(StringRef string,
// This parameter is used in downstream forks, do not remove.
(void)declContext;
auto domain = llvm::StringSwitch<std::optional<AvailabilityDomain>>(string)
.Case("*", AvailabilityDomain::forUniversal())
.Case("swift", AvailabilityDomain::forSwiftLanguageMode())
.Case("_PackageDescription",
AvailabilityDomain::forPackageDescription())
.Default(std::nullopt);
auto domain =
llvm::StringSwitch<std::optional<AvailabilityDomain>>(string)
.Case("*", AvailabilityDomain::forUniversal())
.Case("swift", AvailabilityDomain::forSwiftLanguageMode())
.Case("SwiftLanguageMode", AvailabilityDomain::forSwiftLanguageMode())
.Case("_PackageDescription",
AvailabilityDomain::forPackageDescription())
.Default(std::nullopt);
if (domain)
return domain;
@@ -480,6 +482,8 @@ AvailabilityDomainOrIdentifier::lookUpInDeclContext(
bool hasCustomAvailability =
ctx.LangOpts.hasFeature(Feature::CustomAvailability);
bool hasSwiftRuntimeAvailability =
ctx.LangOpts.hasFeature(Feature::SwiftRuntimeAvailability);
if (!domain) {
auto domainString = identifier.str();
@@ -500,11 +504,32 @@ AvailabilityDomainOrIdentifier::lookUpInDeclContext(
return std::nullopt;
}
if (domain->isCustom() && !hasCustomAvailability &&
!declContext->isInSwiftinterface()) {
diags.diagnose(loc, diag::attr_availability_requires_custom_availability,
*domain);
return std::nullopt;
if (!declContext->isInSwiftinterface()) {
if (domain->isCustom() && !hasCustomAvailability) {
diags.diagnose(loc, diag::availability_domain_requires_feature, *domain,
"CustomAvailability");
return std::nullopt;
}
if (domain->isSwiftLanguageMode()) {
// 'swift' -> 'SwiftLanguageMode'
if (hasSwiftRuntimeAvailability && identifier.str() == "swift") {
diags
.diagnose(loc, diag::availability_domain_renamed, identifier,
"SwiftLanguageMode")
.fixItReplace(SourceRange(loc), "SwiftLanguageMode");
}
if (!hasSwiftRuntimeAvailability &&
identifier.str() == "SwiftLanguageMode") {
// This diagnostic ("Swift requires '-enable-experimental-feature
// SwiftRuntimeAvailability'") is confusing but it's also temporary,
// assuming the experimental feature becomes official.
diags.diagnose(loc, diag::availability_domain_requires_feature, *domain,
"SwiftRuntimeAvailability");
return std::nullopt;
}
}
}
return domain;

View File

@@ -448,6 +448,8 @@ static bool usesFeatureInlineAlways(Decl *decl) {
return false;
}
UNINTERESTING_FEATURE(SwiftRuntimeAvailability)
// ----------------------------------------------------------------------------
// MARK: - FeatureSet
// ----------------------------------------------------------------------------

View File

@@ -771,7 +771,7 @@ using GenericParamKindField = BCFixed<2>;
// the module version.
enum class AvailabilityDomainKind : uint8_t {
Universal = 0,
SwiftLanguage,
SwiftLanguageMode,
PackageDescription,
Embedded,
Platform,

View File

@@ -0,0 +1,16 @@
// RUN: %target-typecheck-verify-swift -parse-as-library -enable-experimental-feature SwiftRuntimeAvailability
// REQUIRES: swift_feature_SwiftRuntimeAvailability
@available(swift 99) // expected-warning {{'swift' has been renamed to 'SwiftLanguageMode'}}{{12-17=SwiftLanguageMode}}
func availableInSwift99() { }
// expected-note@-1 {{'availableInSwift99()' was introduced in Swift 99}}
@available(SwiftLanguageMode 99)
func availableInSwift99LanguageMode() { }
// expected-note@-1 {{'availableInSwift99LanguageMode()' was introduced in Swift 99}}
func testUses() {
availableInSwift99() // expected-error {{'availableInSwift99()' is unavailable in Swift}}
availableInSwift99LanguageMode() // expected-error {{'availableInSwift99LanguageMode()' is unavailable in Swift}}
}

View File

@@ -58,10 +58,13 @@ func testMemberAvailability() {
TestStruct().doAnotherThing() // expected-error {{'doAnotherThing()' is unavailable}}
}
@available(swift 400) // FIXME: This has no effect and should be complained about.
@available(swift 400)
@available(macOS 10.11, *)
extension TestStruct {}
@available(macOS 10.11, *)
@available(swift 400) // FIXME: This has no effect and should be complained about.
@available(swift 400)
extension TestStruct {}
@available(SwiftLanguageMode 400) // expected-error {{Swift requires '-enable-experimental-feature SwiftRuntimeAvailability'}}
extension TestStruct {}