Revert "Introduce adoption mode for Swift features"

This commit is contained in:
Rintaro Ishizaki
2025-03-04 19:13:05 -08:00
committed by GitHub
parent e608b98432
commit 393c59c078
26 changed files with 105 additions and 1422 deletions

View File

@@ -2,7 +2,7 @@
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
@@ -749,56 +749,50 @@ static bool ParseEnabledFeatureArgs(LangOptions &Opts, ArgList &Args,
OPT_enable_experimental_feature, OPT_disable_experimental_feature,
OPT_enable_upcoming_feature, OPT_disable_upcoming_feature)) {
auto &option = A->getOption();
const StringRef argValue = A->getValue();
bool isEnableUpcomingFeatureFlag =
option.matches(OPT_enable_upcoming_feature);
bool isUpcomingFeatureFlag = isEnableUpcomingFeatureFlag ||
option.matches(OPT_disable_upcoming_feature);
bool isEnableFeatureFlag = isEnableUpcomingFeatureFlag ||
option.matches(OPT_enable_experimental_feature);
StringRef value = A->getValue();
bool enableUpcoming = option.matches(OPT_enable_upcoming_feature);
bool isUpcomingFlag =
enableUpcoming || option.matches(OPT_disable_upcoming_feature);
bool enableFeature =
enableUpcoming || option.matches(OPT_enable_experimental_feature);
// Collect some special case pseudo-features which should be processed
// separately.
if (argValue.starts_with("StrictConcurrency") ||
argValue.starts_with("AvailabilityMacro=")) {
if (isEnableFeatureFlag)
psuedoFeatures.push_back(argValue);
if (value.starts_with("StrictConcurrency") ||
value.starts_with("AvailabilityMacro=")) {
if (enableFeature)
psuedoFeatures.push_back(value);
continue;
}
// For all other features, the argument format is `<name>[:adoption]`.
StringRef featureName;
std::optional<StringRef> featureMode;
std::tie(featureName, featureMode) = argValue.rsplit(':');
if (featureMode.value().empty()) {
featureMode = std::nullopt;
}
auto feature = getUpcomingFeature(featureName);
auto feature = getUpcomingFeature(value);
if (feature) {
// Diagnose upcoming features enabled with -enable-experimental-feature.
if (!isUpcomingFeatureFlag)
Diags.diagnose(SourceLoc(), diag::feature_not_experimental, featureName,
isEnableFeatureFlag);
if (!isUpcomingFlag)
Diags.diagnose(SourceLoc(), diag::feature_not_experimental, value,
enableFeature);
} else {
// If -enable-upcoming-feature was used and an upcoming feature was not
// found, diagnose and continue.
if (isUpcomingFeatureFlag) {
Diags.diagnose(SourceLoc(), diag::unrecognized_feature, featureName,
if (isUpcomingFlag) {
Diags.diagnose(SourceLoc(), diag::unrecognized_feature, value,
/*upcoming=*/true);
continue;
}
// If the feature is also not a recognized experimental feature, skip it.
feature = getExperimentalFeature(featureName);
feature = getExperimentalFeature(value);
if (!feature) {
Diags.diagnose(SourceLoc(), diag::unrecognized_feature, featureName,
Diags.diagnose(SourceLoc(), diag::unrecognized_feature, value,
/*upcoming=*/false);
continue;
}
}
// Skip features that are already enabled or disabled.
if (!seenFeatures.insert(*feature).second)
continue;
// If the current language mode enables the feature by default then
// diagnose and skip it.
if (auto firstVersion = getFeatureLanguageVersion(*feature)) {
@@ -815,47 +809,14 @@ static bool ParseEnabledFeatureArgs(LangOptions &Opts, ArgList &Args,
if (Opts.RestrictNonProductionExperimentalFeatures &&
!isFeatureAvailableInProduction(*feature)) {
Diags.diagnose(SourceLoc(),
diag::experimental_not_supported_in_production,
featureName);
diag::experimental_not_supported_in_production, value);
HadError = true;
continue;
}
if (featureMode) {
if (isEnableFeatureFlag) {
const auto isAdoptable = isFeatureAdoptable(*feature);
// Diagnose an invalid mode.
StringRef validModeName = "adoption";
if (*featureMode != validModeName) {
Diags.diagnose(SourceLoc(), diag::invalid_feature_mode, *featureMode,
featureName,
/*didYouMean=*/validModeName,
/*showDidYouMean=*/isAdoptable);
continue;
}
if (!isAdoptable) {
Diags.diagnose(SourceLoc(),
diag::feature_does_not_support_adoption_mode,
featureName);
continue;
}
} else {
// `-disable-*-feature` flags do not support a mode specifier.
Diags.diagnose(SourceLoc(), diag::cannot_disable_feature_with_mode,
option.getPrefixedName(), argValue);
continue;
}
}
// Skip features that are already enabled or disabled.
if (!seenFeatures.insert(*feature).second)
continue;
// Enable the feature if requested.
if (isEnableFeatureFlag)
Opts.enableFeature(*feature, /*forAdoption=*/featureMode.has_value());
if (enableFeature)
Opts.enableFeature(*feature);
}
// Since pseudo-features don't have a boolean on/off state, process them in