Skip to content

[Basic] Make it possible to access some experimental features in production compilers #61844

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/swift/Basic/Feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ FeatureName,
/// Determine whether the given feature is suppressible.
bool isSuppressibleFeature(Feature feature);

/// Check whether the given feature is available in production compilers.
bool isFeatureAvailableInProduction(Feature feature);

/// Determine the in-source name of the given feature.
llvm::StringRef getFeatureName(Feature feature);

Expand Down
48 changes: 25 additions & 23 deletions include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@
#endif

#ifndef EXPERIMENTAL_FEATURE
# define EXPERIMENTAL_FEATURE(FeatureName) \
// 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, 0, #FeatureName, \
langOpts.hasFeature(#FeatureName))
#endif
Expand Down Expand Up @@ -94,63 +96,63 @@ UPCOMING_FEATURE(ForwardTrailingClosures, 286, 6)
UPCOMING_FEATURE(BareSlashRegexLiterals, 354, 6)
UPCOMING_FEATURE(ExistentialAny, 335, 6)

EXPERIMENTAL_FEATURE(StaticAssert)
EXPERIMENTAL_FEATURE(VariadicGenerics)
EXPERIMENTAL_FEATURE(NamedOpaqueTypes)
EXPERIMENTAL_FEATURE(FlowSensitiveConcurrencyCaptures)
EXPERIMENTAL_FEATURE(MoveOnly)
EXPERIMENTAL_FEATURE(OneWayClosureParameters)
EXPERIMENTAL_FEATURE(TypeWitnessSystemInference)
EXPERIMENTAL_FEATURE(ResultBuilderASTTransform)
EXPERIMENTAL_FEATURE(LayoutPrespecialization)
EXPERIMENTAL_FEATURE(StaticAssert, false)
EXPERIMENTAL_FEATURE(VariadicGenerics, false)
EXPERIMENTAL_FEATURE(NamedOpaqueTypes, false)
EXPERIMENTAL_FEATURE(FlowSensitiveConcurrencyCaptures, false)
EXPERIMENTAL_FEATURE(MoveOnly, false)
EXPERIMENTAL_FEATURE(OneWayClosureParameters, false)
EXPERIMENTAL_FEATURE(TypeWitnessSystemInference, false)
EXPERIMENTAL_FEATURE(ResultBuilderASTTransform, true)
EXPERIMENTAL_FEATURE(LayoutPrespecialization, false)

/// Whether to enable experimental differentiable programming features:
/// `@differentiable` declaration attribute, etc.
EXPERIMENTAL_FEATURE(DifferentiableProgramming)
EXPERIMENTAL_FEATURE(DifferentiableProgramming, false)

/// Whether to enable forward mode differentiation.
EXPERIMENTAL_FEATURE(ForwardModeDifferentiation)
EXPERIMENTAL_FEATURE(ForwardModeDifferentiation, false)

/// Whether to enable experimental `AdditiveArithmetic` derived
/// conformances.
EXPERIMENTAL_FEATURE(AdditiveArithmeticDerivedConformances)
EXPERIMENTAL_FEATURE(AdditiveArithmeticDerivedConformances, false)

/// Whether Objective-C completion handler parameters are imported as
/// @Sendable.
EXPERIMENTAL_FEATURE(SendableCompletionHandlers)
EXPERIMENTAL_FEATURE(SendableCompletionHandlers, false)

/// Enables opaque type erasure without also enabling implict dynamic
EXPERIMENTAL_FEATURE(OpaqueTypeErasure)
EXPERIMENTAL_FEATURE(OpaqueTypeErasure, false)

/// Whether to enable experimental @typeWrapper feature which allows to
/// declare a type that controls access to all stored properties of the
/// wrapped type.
EXPERIMENTAL_FEATURE(TypeWrappers)
EXPERIMENTAL_FEATURE(TypeWrappers, false)

/// Whether to perform round-trip testing of the Swift Swift parser.
EXPERIMENTAL_FEATURE(ParserRoundTrip)
EXPERIMENTAL_FEATURE(ParserRoundTrip, false)

/// Whether to perform validation of the parse tree produced by the Swift
/// Swift parser.
EXPERIMENTAL_FEATURE(ParserValidation)
EXPERIMENTAL_FEATURE(ParserValidation, false)

/// Whether to fold sequence expressions in the syntax tree produced by the
/// Swift Swift parser.
EXPERIMENTAL_FEATURE(ParserSequenceFolding)
EXPERIMENTAL_FEATURE(ParserSequenceFolding, false)

/// Enables implicit some while also enabling existential `any`
EXPERIMENTAL_FEATURE(ImplicitSome)
EXPERIMENTAL_FEATURE(ImplicitSome, false)

/// Parse using the Swift (swift-syntax) parser and use ASTGen to generate the
/// corresponding syntax tree.
EXPERIMENTAL_FEATURE(ParserASTGen)
EXPERIMENTAL_FEATURE(ParserASTGen, false)

/// Enable the experimental macros feature.
EXPERIMENTAL_FEATURE(Macros)
EXPERIMENTAL_FEATURE(Macros, false)

/// Parse using the Swift (swift-syntax) parser and use ASTGen to generate the
/// corresponding syntax tree.
EXPERIMENTAL_FEATURE(BuiltinMacros)
EXPERIMENTAL_FEATURE(BuiltinMacros, false)

#undef EXPERIMENTAL_FEATURE
#undef UPCOMING_FEATURE
Expand Down
13 changes: 12 additions & 1 deletion lib/Basic/LangOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,17 @@ bool swift::isSuppressibleFeature(Feature feature) {
llvm_unreachable("covered switch");
}

bool swift::isFeatureAvailableInProduction(Feature feature) {
switch (feature) {
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option) \
case Feature::FeatureName: return true;
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
case Feature::FeatureName: return AvailableInProd;
#include "swift/Basic/Features.def"
}
llvm_unreachable("covered switch");
}

llvm::Optional<Feature> swift::getUpcomingFeature(llvm::StringRef name) {
return llvm::StringSwitch<Optional<Feature>>(name)
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option)
Expand All @@ -455,7 +466,7 @@ llvm::Optional<Feature> swift::getUpcomingFeature(llvm::StringRef name) {
llvm::Optional<Feature> swift::getExperimentalFeature(llvm::StringRef name) {
return llvm::StringSwitch<Optional<Feature>>(name)
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option)
#define EXPERIMENTAL_FEATURE(FeatureName) \
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
.Case(#FeatureName, Feature::FeatureName)
#include "swift/Basic/Features.def"
.Default(None);
Expand Down
8 changes: 5 additions & 3 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,9 +635,11 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
// (non-release) builds for testing purposes.
if (auto feature = getExperimentalFeature(A->getValue())) {
#ifdef NDEBUG
Diags.diagnose(SourceLoc(),
diag::error_experimental_feature_not_available,
A->getValue());
if (!isFeatureAvailableInProduction(*feature)) {
Diags.diagnose(SourceLoc(),
diag::error_experimental_feature_not_available,
A->getValue());
}
#endif

Opts.Features.insert(*feature);
Expand Down