[NFC] Basic: Restrict adoption mode to upcoming and experimental features

This commit is contained in:
Anthony Latsis
2025-03-10 21:30:44 +00:00
parent b3df0dcd08
commit ae70d384e0
8 changed files with 64 additions and 58 deletions

View File

@@ -214,8 +214,7 @@ void BridgedData_free(BridgedData data);
//===----------------------------------------------------------------------===//
enum ENUM_EXTENSIBILITY_ATTR(open) BridgedFeature {
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
FeatureName,
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) FeatureName,
#include "swift/Basic/Features.def"
};

View File

@@ -22,15 +22,13 @@ class LangOptions;
/// Enumeration describing all of the named features.
enum class Feature : uint16_t {
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
FeatureName,
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) FeatureName,
#include "swift/Basic/Features.def"
};
constexpr unsigned numFeatures() {
enum Features {
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
FeatureName,
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) FeatureName,
#include "swift/Basic/Features.def"
NumFeatures
};

View File

@@ -14,7 +14,7 @@
// features.
//
//
// LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description)
// LANGUAGE_FEATURE(FeatureName, SENumber, Description)
//
// The LANGUAGE_FEATURE macro describes each named feature that is
// introduced in Swift. It allows Swift code to check for a particular
@@ -22,20 +22,6 @@
//
// FeatureName: The name given to this feature to be used in source code,
// e.g., AsyncAwait.
// IsAdoptable: Whether the feature implements adoption mode.
//
// If the feature is upcoming (source-breaking) and provides for a
// mechanical code migration, it should implement adoption mode.
//
// Adoption mode is a feature-oriented code migration mechanism: a mode
// of operation that should produce compiler warnings with attached
// fix-its that can be applied to preserve the behavior of the code once
// the upcoming feature is enacted.
// These warnings must belong to a diagnostic group named after the
// feature. Adoption mode itself *and* the fix-its it produces must be
// source and binary compatible with how the code is compiled when the
// feature is disabled.
//
// SENumber: The number assigned to this feature in the Swift Evolution
// process, or 0 if there isn't one.
// Description: A string literal describing the feature.
@@ -106,13 +92,12 @@
#ifndef SUPPRESSIBLE_LANGUAGE_FEATURE
#define SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, \
Description)
LANGUAGE_FEATURE(FeatureName, SENumber, Description)
#endif
#ifndef OPTIONAL_LANGUAGE_FEATURE
#define OPTIONAL_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, Description)
LANGUAGE_FEATURE(FeatureName, SENumber, Description)
#endif
// A feature that's both conditionally-suppressible and experimental.
@@ -133,33 +118,53 @@
#ifndef CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE
#define CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, \
Description) \
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, \
Description)
LANGUAGE_FEATURE(FeatureName, SENumber, Description)
#endif
// An upcoming feature that supports adoption mode.
//
// If the feature is source-breaking and provides for a
// mechanical code migration, it should implement adoption mode.
//
// Adoption mode is a feature-oriented code migration mechanism: a mode
// of operation that should produce compiler warnings with attached
// fix-its that can be applied to preserve the behavior of the code once
// the upcoming feature is enacted.
// These warnings must belong to a diagnostic group named after the
// feature. Adoption mode itself *and* the fix-its it produces must be
// source and binary compatible with how the code is compiled when the
// feature is disabled.
#ifndef ADOPTABLE_UPCOMING_FEATURE
#if defined(UPCOMING_FEATURE)
#define ADOPTABLE_UPCOMING_FEATURE(FeatureName, SENumber, Version) \
UPCOMING_FEATURE(FeatureName, SENumber, Version)
#else
#define ADOPTABLE_UPCOMING_FEATURE(FeatureName, SENumber, Version) \
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/true, SENumber, \
#FeatureName)
LANGUAGE_FEATURE(FeatureName, SENumber, #FeatureName)
#endif
#endif
// See `ADOPTABLE_UPCOMING_FEATURE`.
#ifndef ADOPTABLE_EXPERIMENTAL_FEATURE
#if defined(EXPERIMENTAL_FEATURE)
#define ADOPTABLE_EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd)
#else
#define ADOPTABLE_EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
LANGUAGE_FEATURE(FeatureName, 0, #FeatureName)
#endif
#endif
#ifndef UPCOMING_FEATURE
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, \
#FeatureName)
LANGUAGE_FEATURE(FeatureName, SENumber, #FeatureName)
#endif
#ifndef EXPERIMENTAL_FEATURE
// Warning: setting `AvailableInProd` to `true` on a feature means that the
// flag cannot be dropped in the future.
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, 0, #FeatureName)
LANGUAGE_FEATURE(FeatureName, 0, #FeatureName)
#endif
#ifndef EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE
@@ -169,8 +174,7 @@
#ifndef BASELINE_LANGUAGE_FEATURE
#define BASELINE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
LANGUAGE_FEATURE(FeatureName, /*IsAdoptable=*/false, SENumber, \
Description)
LANGUAGE_FEATURE(FeatureName, SENumber, Description)
#endif
BASELINE_LANGUAGE_FEATURE(AsyncAwait, 296, "async/await")
@@ -242,17 +246,12 @@ BASELINE_LANGUAGE_FEATURE(BodyMacros, 415, "Function body macros")
SUPPRESSIBLE_LANGUAGE_FEATURE(SendingArgsAndResults, 430, "Sending arg and results")
BASELINE_LANGUAGE_FEATURE(BorrowingSwitch, 432, "Noncopyable type pattern matching")
CONDITIONALLY_SUPPRESSIBLE_LANGUAGE_FEATURE(IsolatedAny, 431, "@isolated(any) function types")
LANGUAGE_FEATURE(IsolatedAny2, /*IsAdoptable=*/false, 431,
"@isolated(any) function types")
LANGUAGE_FEATURE(ObjCImplementation, /*IsAdoptable=*/false, 436,
"@objc @implementation extensions")
LANGUAGE_FEATURE(NonescapableTypes, /*IsAdoptable=*/false, 446,
"Nonescapable types")
LANGUAGE_FEATURE(BuiltinEmplaceTypedThrows, /*IsAdoptable=*/false, 0,
"Builtin.emplace typed throws")
LANGUAGE_FEATURE(IsolatedAny2, 431, "@isolated(any) function types")
LANGUAGE_FEATURE(ObjCImplementation, 436, "@objc @implementation extensions")
LANGUAGE_FEATURE(NonescapableTypes, 446, "Nonescapable types")
LANGUAGE_FEATURE(BuiltinEmplaceTypedThrows, 0, "Builtin.emplace typed throws")
SUPPRESSIBLE_LANGUAGE_FEATURE(MemorySafetyAttributes, 458, "@unsafe attribute")
LANGUAGE_FEATURE(ValueGenerics, /*IsAdoptable=*/ false, 452,
"Value generics feature (integer generics)")
LANGUAGE_FEATURE(ValueGenerics, 452, "Value generics feature (integer generics)")
// Swift 6
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
@@ -518,6 +517,7 @@ EXPERIMENTAL_FEATURE(CompileTimeValues, true)
#undef EXPERIMENTAL_FEATURE
#undef UPCOMING_FEATURE
#undef ADOPTABLE_UPCOMING_FEATURE
#undef ADOPTABLE_EXPERIMENTAL_FEATURE
#undef BASELINE_LANGUAGE_FEATURE
#undef OPTIONAL_LANGUAGE_FEATURE
#undef CONDITIONALLY_SUPPRESSIBLE_EXPERIMENTAL_FEATURE

View File

@@ -3267,7 +3267,7 @@ suppressingFeatureExecutionAttribute(PrintOptions &options,
static void suppressingFeature(PrintOptions &options, Feature feature,
llvm::function_ref<void()> action) {
switch (feature) {
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
case Feature::FeatureName: \
llvm_unreachable("not a suppressible feature");
#define SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \

View File

@@ -45,7 +45,7 @@ static bool usesTypeMatching(Decl *decl, llvm::function_ref<bool(Type)> fn) {
#define BASELINE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
static bool usesFeature##FeatureName(Decl *decl) { return false; }
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description)
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
#include "swift/Basic/Features.def"
#define UNINTERESTING_FEATURE(FeatureName) \
@@ -550,7 +550,7 @@ void FeatureSet::collectFeaturesUsed(Decl *decl, InsertOrRemove operation) {
// Go through each of the features, checking whether the
// declaration uses that feature.
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
if (CHECK(usesFeature##FeatureName)) \
collectRequiredFeature(Feature::FeatureName, operation);
#define SUPPRESSIBLE_LANGUAGE_FEATURE(FeatureName, SENumber, Description) \

View File

@@ -18,7 +18,7 @@ using namespace swift;
bool swift::isFeatureAvailableInProduction(Feature feature) {
switch (feature) {
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
case Feature::FeatureName: \
return true;
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
@@ -31,7 +31,7 @@ bool swift::isFeatureAvailableInProduction(Feature feature) {
llvm::StringRef swift::getFeatureName(Feature feature) {
switch (feature) {
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
case Feature::FeatureName: \
return #FeatureName;
#include "swift/Basic/Features.def"
@@ -41,7 +41,7 @@ llvm::StringRef swift::getFeatureName(Feature feature) {
std::optional<Feature> swift::getUpcomingFeature(llvm::StringRef name) {
return llvm::StringSwitch<std::optional<Feature>>(name)
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description)
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
.Case(#FeatureName, Feature::FeatureName)
#include "swift/Basic/Features.def"
@@ -50,7 +50,7 @@ std::optional<Feature> swift::getUpcomingFeature(llvm::StringRef name) {
std::optional<Feature> swift::getExperimentalFeature(llvm::StringRef name) {
return llvm::StringSwitch<std::optional<Feature>>(name)
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description)
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
.Case(#FeatureName, Feature::FeatureName)
#include "swift/Basic/Features.def"
@@ -59,7 +59,7 @@ std::optional<Feature> swift::getExperimentalFeature(llvm::StringRef name) {
std::optional<unsigned> swift::getFeatureLanguageVersion(Feature feature) {
switch (feature) {
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description)
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
case Feature::FeatureName: \
return Version;
@@ -71,16 +71,25 @@ std::optional<unsigned> swift::getFeatureLanguageVersion(Feature feature) {
bool swift::isFeatureAdoptable(Feature feature) {
switch (feature) {
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
case Feature::FeatureName: \
return IsAdoptable;
#define ADOPTABLE_UPCOMING_FEATURE(FeatureName, SENumber, Version)
#define ADOPTABLE_EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd)
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
case Feature::FeatureName:
#include "swift/Basic/Features.def"
return false;
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description)
#define ADOPTABLE_UPCOMING_FEATURE(FeatureName, SENumber, Version) \
case Feature::FeatureName:
#define ADOPTABLE_EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
case Feature::FeatureName:
#include "swift/Basic/Features.def"
return true;
}
}
bool swift::includeInModuleInterface(Feature feature) {
switch (feature) {
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
case Feature::FeatureName: \
return true;
#define EXPERIMENTAL_FEATURE_EXCLUDED_FROM_MODULE_INTERFACE(FeatureName, \

View File

@@ -35,7 +35,7 @@ using namespace swift;
LangOptions::LangOptions() {
// Add all promoted language features
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
this->enableFeature(Feature::FeatureName);
#define UPCOMING_FEATURE(FeatureName, SENumber, Version)
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd)
@@ -348,7 +348,7 @@ bool LangOptions::hasFeature(Feature feature) const {
bool LangOptions::hasFeature(llvm::StringRef featureName) const {
auto feature = llvm::StringSwitch<std::optional<Feature>>(featureName)
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
.Case(#FeatureName, Feature::FeatureName)
#include "swift/Basic/Features.def"
.Default(std::nullopt);

View File

@@ -30,7 +30,7 @@ def language_feature(feature_name, enabled):
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) language_feature(#FeatureName, True)
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) language_feature(#FeatureName, #AvailableInProd == "true")
#define LANGUAGE_FEATURE(FeatureName, IsAdoptable, SENumber, Description) \
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \
language_feature(#FeatureName, True)
#include <swift/Basic/Features.def>