Skip to content

Commit 2d8465b

Browse files
committed
AST: Introduce the SwiftLanguageMode availability domain spelling.
Require `-enable-experimental-feature SwiftRuntimeAvailability` to use this new spelling.
1 parent 4e9a883 commit 2d8465b

File tree

8 files changed

+69
-17
lines changed

8 files changed

+69
-17
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6986,6 +6986,12 @@ WARNING(availability_unsupported_version_number, none,
69866986
WARNING(availability_invalid_version_number_for_domain, none,
69876987
"'%0' is not a valid version number for %1",
69886988
(llvm::VersionTuple, AvailabilityDomain))
6989+
WARNING(availability_domain_renamed, none,
6990+
"%0 has been renamed to '%1'",
6991+
(Identifier, StringRef))
6992+
ERROR(availability_domain_requires_feature, none,
6993+
"%0 requires '-enable-experimental-feature %1'",
6994+
(AvailabilityDomain, StringRef))
69896995

69906996
WARNING(attr_availability_expected_deprecated_version, none,
69916997
"expected version number with 'deprecated' in '%0' attribute for %1",
@@ -6996,9 +7002,6 @@ WARNING(attr_availability_cannot_be_used_for_domain, none,
69967002
WARNING(attr_availability_expected_version_spec, none,
69977003
"expected 'introduced', 'deprecated', or 'obsoleted' in '%0' attribute "
69987004
"for %1", (const DeclAttribute, AvailabilityDomain))
6999-
ERROR(attr_availability_requires_custom_availability, none,
7000-
"%0 requires '-enable-experimental-feature CustomAvailability'",
7001-
(AvailabilityDomain))
70027005
ERROR(attr_availability_domain_access, none,
70037006
"availability domain '%0' is "
70047007
"%select{private|fileprivate|internal|package|%error|%error}1 "

include/swift/Basic/Features.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,9 @@ EXPERIMENTAL_FEATURE(BorrowAndMutateAccessors, false)
556556
/// Allow use of @inline(always) attribute
557557
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(InlineAlways, false)
558558

559+
/// Allow use of 'Swift' (Swift runtime version) in @available attributes
560+
EXPERIMENTAL_FEATURE(SwiftRuntimeAvailability, true)
561+
559562
#undef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
560563
#undef EXPERIMENTAL_FEATURE
561564
#undef UPCOMING_FEATURE

lib/AST/AvailabilityDomain.cpp

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,14 @@ AvailabilityDomain::builtinDomainForString(StringRef string,
107107
// This parameter is used in downstream forks, do not remove.
108108
(void)declContext;
109109

110-
auto domain = llvm::StringSwitch<std::optional<AvailabilityDomain>>(string)
111-
.Case("*", AvailabilityDomain::forUniversal())
112-
.Case("swift", AvailabilityDomain::forSwiftLanguageMode())
113-
.Case("_PackageDescription",
114-
AvailabilityDomain::forPackageDescription())
115-
.Default(std::nullopt);
110+
auto domain =
111+
llvm::StringSwitch<std::optional<AvailabilityDomain>>(string)
112+
.Case("*", AvailabilityDomain::forUniversal())
113+
.Case("swift", AvailabilityDomain::forSwiftLanguageMode())
114+
.Case("SwiftLanguageMode", AvailabilityDomain::forSwiftLanguageMode())
115+
.Case("_PackageDescription",
116+
AvailabilityDomain::forPackageDescription())
117+
.Default(std::nullopt);
116118

117119
if (domain)
118120
return domain;
@@ -480,6 +482,8 @@ AvailabilityDomainOrIdentifier::lookUpInDeclContext(
480482

481483
bool hasCustomAvailability =
482484
ctx.LangOpts.hasFeature(Feature::CustomAvailability);
485+
bool hasSwiftRuntimeAvailability =
486+
ctx.LangOpts.hasFeature(Feature::SwiftRuntimeAvailability);
483487

484488
if (!domain) {
485489
auto domainString = identifier.str();
@@ -500,11 +504,32 @@ AvailabilityDomainOrIdentifier::lookUpInDeclContext(
500504
return std::nullopt;
501505
}
502506

503-
if (domain->isCustom() && !hasCustomAvailability &&
504-
!declContext->isInSwiftinterface()) {
505-
diags.diagnose(loc, diag::attr_availability_requires_custom_availability,
506-
*domain);
507-
return std::nullopt;
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;
512+
}
513+
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+
}
532+
}
508533
}
509534

510535
return domain;

lib/AST/FeatureSet.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,8 @@ static bool usesFeatureInlineAlways(Decl *decl) {
448448
return false;
449449
}
450450

451+
UNINTERESTING_FEATURE(SwiftRuntimeAvailability)
452+
451453
// ----------------------------------------------------------------------------
452454
// MARK: - FeatureSet
453455
// ----------------------------------------------------------------------------

lib/Serialization/ModuleFormat.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ using GenericParamKindField = BCFixed<2>;
771771
// the module version.
772772
enum class AvailabilityDomainKind : uint8_t {
773773
Universal = 0,
774-
SwiftLanguage,
774+
SwiftLanguageMode,
775775
PackageDescription,
776776
Embedded,
777777
Platform,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// RUN: %target-typecheck-verify-swift -parse-as-library -enable-experimental-feature SwiftRuntimeAvailability
2+
3+
// REQUIRES: swift_feature_SwiftRuntimeAvailability
4+
5+
@available(swift 99) // expected-warning {{'swift' has been renamed to 'SwiftLanguageMode'}}{{12-17=SwiftLanguageMode}}
6+
func availableInSwift99() { }
7+
// expected-note@-1 {{'availableInSwift99()' was introduced in Swift 99}}
8+
9+
@available(SwiftLanguageMode 99)
10+
func availableInSwift99LanguageMode() { }
11+
// expected-note@-1 {{'availableInSwift99LanguageMode()' was introduced in Swift 99}}
12+
13+
func testUses() {
14+
availableInSwift99() // expected-error {{'availableInSwift99()' is unavailable in Swift}}
15+
availableInSwift99LanguageMode() // expected-error {{'availableInSwift99LanguageMode()' is unavailable in Swift}}
16+
}

test/attr/attr_availability_swift.swift renamed to test/attr/attr_availability_swift_language_mode.swift

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,13 @@ func testMemberAvailability() {
5858
TestStruct().doAnotherThing() // expected-error {{'doAnotherThing()' is unavailable}}
5959
}
6060

61-
@available(swift 400) // FIXME: This has no effect and should be complained about.
61+
@available(swift 400)
6262
@available(macOS 10.11, *)
6363
extension TestStruct {}
6464

6565
@available(macOS 10.11, *)
66-
@available(swift 400) // FIXME: This has no effect and should be complained about.
66+
@available(swift 400)
67+
extension TestStruct {}
68+
69+
@available(SwiftLanguageMode 400) // expected-error {{Swift requires '-enable-experimental-feature SwiftRuntimeAvailability'}}
6770
extension TestStruct {}

0 commit comments

Comments
 (0)