mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Revert "Introduce adoption mode for Swift features"
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user