Skip to content

Commit a317fad

Browse files
committed
Add -enable-upcoming-feature X command-line argument.
Introduce the `-enable-upcoming-feature X` command-line argument to allow one to opt into features that will be enabled in an upcoming language mode. Stage in several features this way (`ConciseMagicFile`, `ForwardTrailingClosures`, `BareSlashRegexLiterals`).
1 parent c443b1a commit a317fad

File tree

11 files changed

+55
-12
lines changed

11 files changed

+55
-12
lines changed

include/swift/AST/DiagnosticsFrontend.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ ERROR(error_experimental_feature_not_available, none,
4040
"experimental feature '%0' cannot be enabled in a production compiler",
4141
(StringRef))
4242

43+
ERROR(error_upcoming_feature_on_by_default, none,
44+
"upcoming feature '%0' is already enabled as of Swift version %1",
45+
(StringRef, unsigned))
46+
4347
ERROR(error_unknown_library_level, none,
4448
"unknown library level '%0', "
4549
"expected one of 'api', 'spi' or 'other'", (StringRef))

include/swift/Basic/Feature.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ inline bool featureImpliesFeature(Feature feature, Feature implied) {
5353
}
5454

5555
/// Get the feature corresponding to this "future" feature, if there is one.
56-
llvm::Optional<Feature> getFutureFeature(llvm::StringRef name);
56+
llvm::Optional<Feature> getUpcomingFeature(llvm::StringRef name);
5757

5858
/// Get the feature corresponding to this "experimental" feature, if there is
5959
/// one.

include/swift/Basic/Features.def

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@
4848
LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option)
4949
#endif
5050

51-
#ifndef FUTURE_FEATURE
52-
# define FUTURE_FEATURE(FeatureName, SENumber, Version) \
51+
#ifndef UPCOMING_FEATURE
52+
# define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
5353
LANGUAGE_FEATURE(FeatureName, SENumber, #FeatureName, \
5454
langOpts.hasFeature(#FeatureName))
5555
#endif
@@ -90,9 +90,9 @@ SUPPRESSIBLE_LANGUAGE_FEATURE(PrimaryAssociatedTypes2, 346, "Primary associated
9090
SUPPRESSIBLE_LANGUAGE_FEATURE(UnavailableFromAsync, 0, "@_unavailableFromAsync", true)
9191
SUPPRESSIBLE_LANGUAGE_FEATURE(NoAsyncAvailability, 340, "@available(*, noasync)", true)
9292

93-
FUTURE_FEATURE(ConciseMagicFile, 274, 6)
94-
FUTURE_FEATURE(ForwardTrailingClosures, 286, 6)
95-
FUTURE_FEATURE(BareSlashRegexLiterals, 354, 6)
93+
UPCOMING_FEATURE(ConciseMagicFile, 274, 6)
94+
UPCOMING_FEATURE(ForwardTrailingClosures, 286, 6)
95+
UPCOMING_FEATURE(BareSlashRegexLiterals, 354, 6)
9696

9797
EXPERIMENTAL_FEATURE(StaticAssert)
9898
EXPERIMENTAL_FEATURE(VariadicGenerics)
@@ -118,6 +118,6 @@ EXPERIMENTAL_FEATURE(AdditiveArithmeticDerivedConformances)
118118
EXPERIMENTAL_FEATURE(SendableCompletionHandlers)
119119

120120
#undef EXPERIMENTAL_FEATURE
121-
#undef FUTURE_FEATURE
121+
#undef UPCOMING_FEATURE
122122
#undef SUPPRESSIBLE_LANGUAGE_FEATURE
123123
#undef LANGUAGE_FEATURE

include/swift/Basic/LangOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "llvm/ADT/SmallString.h"
2929
#include "llvm/ADT/SmallSet.h"
3030
#include "llvm/ADT/SmallVector.h"
31+
#include "llvm/ADT/SmallSet.h"
3132
#include "llvm/ADT/StringRef.h"
3233
#include "llvm/ADT/Triple.h"
3334
#include "llvm/Support/Regex.h"

include/swift/Option/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,11 @@ def enable_experimental_feature :
696696
Flags<[FrontendOption]>,
697697
HelpText<"Enable an experimental feature">;
698698

699+
def enable_upcoming_feature : Separate<["-"], "enable-upcoming-feature">,
700+
Flags<[FrontendOption]>,
701+
HelpText<"Enable a feature that will be introduced in an upcoming language "
702+
"version">;
703+
699704
def Rpass_EQ : Joined<["-"], "Rpass=">,
700705
Flags<[FrontendOption]>,
701706
HelpText<"Report performed transformations by optimization passes whose "

lib/Basic/LangOptions.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ bool LangOptions::hasFeature(Feature feature) const {
240240
}
241241

242242
bool LangOptions::hasFeature(llvm::StringRef featureName) const {
243-
if (auto feature = getFutureFeature(featureName))
243+
if (auto feature = getUpcomingFeature(featureName))
244244
return hasFeature(*feature);
245245

246246
if (auto feature = getExperimentalFeature(featureName))
@@ -434,10 +434,10 @@ bool swift::isSuppressibleFeature(Feature feature) {
434434
llvm_unreachable("covered switch");
435435
}
436436

437-
llvm::Optional<Feature> swift::getFutureFeature(llvm::StringRef name) {
437+
llvm::Optional<Feature> swift::getUpcomingFeature(llvm::StringRef name) {
438438
return llvm::StringSwitch<Optional<Feature>>(name)
439439
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option)
440-
#define FUTURE_FEATURE(FeatureName, SENumber, Version) \
440+
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
441441
.Case(#FeatureName, Feature::FeatureName)
442442
#include "swift/Basic/Features.def"
443443
.Default(None);
@@ -455,7 +455,7 @@ llvm::Optional<Feature> swift::getExperimentalFeature(llvm::StringRef name) {
455455
llvm::Optional<unsigned> swift::getFeatureLanguageVersion(Feature feature) {
456456
switch (feature) {
457457
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option)
458-
#define FUTURE_FEATURE(FeatureName, SENumber, Version) \
458+
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
459459
case Feature::FeatureName: return Version;
460460
#include "swift/Basic/Features.def"
461461
default: return None;

lib/Driver/ToolChains.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
237237
inputArgs.AddLastArg(arguments, options::OPT_warn_concurrency);
238238
inputArgs.AddLastArg(arguments, options::OPT_strict_concurrency);
239239
inputArgs.AddAllArgs(arguments, options::OPT_enable_experimental_feature);
240+
inputArgs.AddAllArgs(arguments, options::OPT_enable_upcoming_feature);
240241
inputArgs.AddLastArg(arguments, options::OPT_warn_implicit_overrides);
241242
inputArgs.AddLastArg(arguments, options::OPT_typo_correction_limit);
242243
inputArgs.AddLastArg(arguments, options::OPT_enable_app_extension);

lib/Frontend/CompilerInvocation.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "ArgsToFrontendOptionsConverter.h"
1717
#include "swift/AST/DiagnosticsFrontend.h"
18+
#include "swift/Basic/Feature.h"
1819
#include "swift/Basic/Platform.h"
1920
#include "swift/Option/Options.h"
2021
#include "swift/Option/SanitizerOptions.h"
@@ -637,6 +638,26 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
637638
}
638639
}
639640

641+
// Map historical flags over to future features.
642+
for (const Arg *A : Args.filtered(OPT_enable_upcoming_feature)) {
643+
// Ignore unknown features.
644+
auto feature = getUpcomingFeature(A->getValue());
645+
if (!feature)
646+
continue;
647+
648+
// Check if this feature was introduced already in this language version.
649+
if (auto firstVersion = getFeatureLanguageVersion(*feature)) {
650+
if (Opts.isSwiftVersionAtLeast(*firstVersion)) {
651+
Diags.diagnose(SourceLoc(), diag::error_upcoming_feature_on_by_default,
652+
A->getValue(), *firstVersion);
653+
continue;
654+
}
655+
}
656+
657+
// Add the feature.
658+
Opts.Features.insert(*feature);
659+
}
660+
640661
// Map historical flags over to experimental features. We do this for all
641662
// compilers because that's how existing experimental feature flags work.
642663
if (Args.hasArg(OPT_enable_experimental_variadic_generics))

lib/Parse/ParseIfConfig.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ class EvaluateIfConfigCondition :
484484
bool isKnownFeature = llvm::StringSwitch<bool>(Name)
485485
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option) \
486486
.Case("$" #FeatureName, Option)
487+
#define UPCOMING_FEATURE(FeatureName, SENumber, Version)
487488
#include "swift/Basic/Features.def"
488489
.Default(false);
489490

test/Frontend/upcoming_feature.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
// It's fine to provide a feature that we don't know about
3+
// RUN: %target-swift-frontend -typecheck -enable-upcoming-feature UnknownFeature %s
4+
5+
// It's not fine to provide a feature that's in the specified language version.
6+
// RUN: not %target-swift-frontend -typecheck -enable-upcoming-feature ConciseMagicFile -swift-version 6 %s 2>&1 | %FileCheck %s
7+
// REQUIRES: asserts
8+
9+
// CHECK: error: upcoming feature 'ConciseMagicFile' is already enabled as of Swift version 6

test/Sema/diag_mismatched_magic_literals_swift6.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
// The future "Swift 6 mode" behavior is staged in behind `-enable-experimental-concise-pound-file`.
1+
// The upcoming "Swift 6 mode" behavior is staged in behind `-enable-experimental-concise-pound-file`.
22
// RUN: %target-typecheck-verify-swift -enable-experimental-concise-pound-file
3+
// RUN: %target-typecheck-verify-swift -enable-upcoming-feature ConciseMagicFile
34

45
// And is also available in Swift 6 mode on asserts compilers.
56
// RUN: %target-typecheck-verify-swift -swift-version 6

0 commit comments

Comments
 (0)