Skip to content
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
8 changes: 8 additions & 0 deletions include/swift/Basic/Feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#ifndef SWIFT_BASIC_FEATURES_H
#define SWIFT_BASIC_FEATURES_H

#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"

namespace swift {
Expand Down Expand Up @@ -51,10 +52,17 @@ inline bool featureImpliesFeature(Feature feature, Feature implied) {
return (unsigned) feature < (unsigned) implied;
}

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

/// Get the feature corresponding to this "experimental" feature, if there is
/// one.
llvm::Optional<Feature> getExperimentalFeature(llvm::StringRef name);

/// Get the major language version in which this feature was introduced, or
/// \c None if it does not have such a version.
llvm::Optional<unsigned> getFeatureLanguageVersion(Feature feature);

}

#endif // SWIFT_BASIC_FEATURES_H
11 changes: 11 additions & 0 deletions include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@
LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option)
#endif

#ifndef FUTURE_FEATURE
# define FUTURE_FEATURE(FeatureName, SENumber, Version) \
LANGUAGE_FEATURE(FeatureName, SENumber, #FeatureName, \
langOpts.hasFeature(#FeatureName))
#endif

#ifndef EXPERIMENTAL_FEATURE
# define EXPERIMENTAL_FEATURE(FeatureName) \
LANGUAGE_FEATURE(FeatureName, 0, #FeatureName, \
Expand Down Expand Up @@ -83,6 +89,10 @@ SUPPRESSIBLE_LANGUAGE_FEATURE(PrimaryAssociatedTypes2, 346, "Primary associated
SUPPRESSIBLE_LANGUAGE_FEATURE(UnavailableFromAsync, 0, "@_unavailableFromAsync", true)
SUPPRESSIBLE_LANGUAGE_FEATURE(NoAsyncAvailability, 340, "@available(*, noasync)", true)

FUTURE_FEATURE(ConciseMagicFile, 274, 6)
FUTURE_FEATURE(ForwardTrailingClosures, 286, 6)
FUTURE_FEATURE(BareSlashRegexLiterals, 354, 6)

EXPERIMENTAL_FEATURE(StaticAssert)
EXPERIMENTAL_FEATURE(VariadicGenerics)
EXPERIMENTAL_FEATURE(NamedOpaqueTypes)
Expand All @@ -92,5 +102,6 @@ EXPERIMENTAL_FEATURE(OneWayClosureParameters)
EXPERIMENTAL_FEATURE(TypeWitnessSystemInference)

#undef EXPERIMENTAL_FEATURE
#undef FUTURE_FEATURE
#undef SUPPRESSIBLE_LANGUAGE_FEATURE
#undef LANGUAGE_FEATURE
7 changes: 3 additions & 4 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,9 @@ namespace swift {
/// The set of features that have been enabled.
llvm::SmallSet<Feature, 2> Features;

/// Temporary flag to support LLDB's transition to using \c Features.
bool EnableBareSlashRegexLiterals = false;

/// Use Clang function types for computing canonical types.
/// If this option is false, the clang function types will still be computed
/// but will not be used for checking type equality.
Expand Down Expand Up @@ -529,10 +532,6 @@ namespace swift {
/// Enables dumping type witness systems from associated type inference.
bool DumpTypeWitnessSystems = false;

/// Enables `/.../` syntax regular-expression literals. This requires
/// experimental string processing. Note this does not affect `#/.../#`.
bool EnableBareSlashRegexLiterals = false;

/// Sets the target we are building for and updates platform conditions
/// to match.
///
Expand Down
12 changes: 12 additions & 0 deletions lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2999,6 +2999,18 @@ static bool usesFeatureNoAsyncAvailability(Decl *decl) {
return decl->getAttrs().getNoAsync(decl->getASTContext()) != nullptr;
}

static bool usesFeatureConciseMagicFile(Decl *decl) {
return false;
}

static bool usesFeatureForwardTrailingClosures(Decl *decl) {
return false;
}

static bool usesFeatureBareSlashRegexLiterals(Decl *decl) {
return false;
}

static bool usesFeatureVariadicGenerics(Decl *decl) {
return false;
}
Expand Down
30 changes: 30 additions & 0 deletions lib/Basic/LangOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "swift/Config.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/raw_ostream.h"
#include <limits.h>

Expand Down Expand Up @@ -228,10 +229,20 @@ bool LangOptions::hasFeature(Feature feature) const {
if (Features.contains(feature))
return true;

if (feature == Feature::BareSlashRegexLiterals &&
EnableBareSlashRegexLiterals)
return true;

if (auto version = getFeatureLanguageVersion(feature))
return isSwiftVersionAtLeast(*version);

return false;
}

bool LangOptions::hasFeature(llvm::StringRef featureName) const {
if (auto feature = getFutureFeature(featureName))
return hasFeature(*feature);

if (auto feature = getExperimentalFeature(featureName))
return hasFeature(*feature);

Expand Down Expand Up @@ -423,6 +434,15 @@ bool swift::isSuppressibleFeature(Feature feature) {
llvm_unreachable("covered switch");
}

llvm::Optional<Feature> swift::getFutureFeature(llvm::StringRef name) {
return llvm::StringSwitch<Optional<Feature>>(name)
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option)
#define FUTURE_FEATURE(FeatureName, SENumber, Version) \
.Case(#FeatureName, Feature::FeatureName)
#include "swift/Basic/Features.def"
.Default(None);
}

llvm::Optional<Feature> swift::getExperimentalFeature(llvm::StringRef name) {
return llvm::StringSwitch<Optional<Feature>>(name)
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option)
Expand All @@ -432,6 +452,16 @@ llvm::Optional<Feature> swift::getExperimentalFeature(llvm::StringRef name) {
.Default(None);
}

llvm::Optional<unsigned> swift::getFeatureLanguageVersion(Feature feature) {
switch (feature) {
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option)
#define FUTURE_FEATURE(FeatureName, SENumber, Version) \
case Feature::FeatureName: return Version;
#include "swift/Basic/Features.def"
default: return None;
}
}

DiagnosticBehavior LangOptions::getAccessNoteFailureLimit() const {
switch (AccessNoteBehavior) {
case AccessNoteDiagnosticBehavior::Ignore:
Expand Down
46 changes: 23 additions & 23 deletions lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,25 +486,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
= A->getOption().matches(OPT_enable_deserialization_recovery);
}

// Whether '/.../' regex literals are enabled. This implies experimental
// string processing.
if (Args.hasArg(OPT_enable_bare_slash_regex)) {
Opts.EnableBareSlashRegexLiterals = true;
Opts.EnableExperimentalStringProcessing = true;
}

// Experimental string processing.
if (auto A = Args.getLastArg(OPT_enable_experimental_string_processing,
OPT_disable_experimental_string_processing)) {
Opts.EnableExperimentalStringProcessing =
A->getOption().matches(OPT_enable_experimental_string_processing);

// When experimental string processing is explicitly disabled, also disable
// forward slash regex `/.../`.
if (!Opts.EnableExperimentalStringProcessing)
Opts.EnableBareSlashRegexLiterals = false;
}

Opts.EnableExperimentalBoundGenericExtensions |=
Args.hasArg(OPT_enable_experimental_bound_generic_extensions);

Expand Down Expand Up @@ -632,6 +613,29 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.addCustomConditionalCompilationFlag(A->getValue());
}

// Determine whether string processing is enabled
Opts.EnableExperimentalStringProcessing =
Args.hasFlag(OPT_enable_experimental_string_processing,
OPT_disable_experimental_string_processing,
Args.hasArg(OPT_enable_bare_slash_regex));

// Add a future feature if it is not already implied by the language version.
auto addFutureFeatureIfNotImplied = [&](Feature feature) {
// Check if this feature was introduced already in this language version.
if (auto firstVersion = getFeatureLanguageVersion(feature)) {
if (Opts.isSwiftVersionAtLeast(*firstVersion))
return;
}

Opts.Features.insert(feature);
};

// Map historical flags over to future features.
if (Args.hasArg(OPT_enable_experimental_concise_pound_file))
addFutureFeatureIfNotImplied(Feature::ConciseMagicFile);
if (Args.hasArg(OPT_enable_bare_slash_regex))
addFutureFeatureIfNotImplied(Feature::BareSlashRegexLiterals);

for (const Arg *A : Args.filtered(OPT_enable_experimental_feature)) {
// If this is a known experimental feature, allow it in +Asserts
// (non-release) builds for testing purposes.
Expand Down Expand Up @@ -759,10 +763,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
A->getAsString(Args), A->getValue());
}

Opts.EnableConcisePoundFile =
Args.hasArg(OPT_enable_experimental_concise_pound_file) ||
Opts.EffectiveLanguageVersion.isVersionAtLeast(6);

Opts.EnableCrossImportOverlays =
Args.hasFlag(OPT_enable_cross_import_overlays,
OPT_disable_cross_import_overlays,
Expand Down
5 changes: 3 additions & 2 deletions lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,8 @@ UnresolvedDeclRefExpr *Parser::parseExprOperator() {
}

void Parser::tryLexRegexLiteral(bool forUnappliedOperator) {
if (!Context.LangOpts.EnableBareSlashRegexLiterals)
if (!Context.LangOpts.hasFeature(Feature::BareSlashRegexLiterals) ||
!Context.LangOpts.EnableExperimentalStringProcessing)
return;

// Check to see if we have a regex literal `/.../`, optionally with a prefix
Expand Down Expand Up @@ -1114,7 +1115,7 @@ getMagicIdentifierLiteralKind(tok Kind, const LangOptions &Opts) {
switch (Kind) {
case tok::pound_file:
// TODO: Enable by default at the next source break. (SR-13199)
return Opts.EnableConcisePoundFile
return Opts.hasFeature(Feature::ConciseMagicFile)
? MagicIdentifierLiteralExpr::FileIDSpelledAsFile
: MagicIdentifierLiteralExpr::FilePathSpelledAsFile;
#define MAGIC_IDENTIFIER_TOKEN(NAME, TOKEN) \
Expand Down
4 changes: 2 additions & 2 deletions lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ static bool matchCallArgumentsImpl(
// way to successfully match arguments to parameters.
if (!parameterRequiresArgument(params, paramInfo, paramIdx) &&
!param.getPlainType()->getASTContext().LangOpts
.isSwiftVersionAtLeast(6) &&
.hasFeature(Feature::ForwardTrailingClosures) &&
anyParameterRequiresArgument(
params, paramInfo, paramIdx + 1,
nextArgIdx + 1 < numArgs
Expand Down Expand Up @@ -934,7 +934,7 @@ static bool requiresBothTrailingClosureDirections(

// If backward matching is disabled, only scan forward.
ASTContext &ctx = params.front().getPlainType()->getASTContext();
if (ctx.LangOpts.isSwiftVersionAtLeast(6))
if (ctx.LangOpts.hasFeature(Feature::ForwardTrailingClosures))
return false;

// If there are at least two parameters that meet the backward scan's
Expand Down
4 changes: 1 addition & 3 deletions tools/libSwiftSyntaxParser/libSwiftSyntaxParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,9 +512,7 @@ swiftparse_client_node_t SynParser::parse(const char *source, size_t len) {

// Always enable bare /.../ regex literal in syntax parser.
langOpts.EnableExperimentalStringProcessing = true;
if (EnableBareSlashRegexLiteral && *EnableBareSlashRegexLiteral) {
langOpts.EnableBareSlashRegexLiterals = true;
}
langOpts.Features.insert(Feature::BareSlashRegexLiterals);
if (EffectiveLanguageVersion) {
langOpts.EffectiveLanguageVersion = *EffectiveLanguageVersion;
}
Expand Down
2 changes: 1 addition & 1 deletion tools/swift-ide-test/swift-ide-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4305,7 +4305,7 @@ int main(int argc, char *argv[]) {
InitInvok.getLangOptions().EnableExperimentalStringProcessing = true;
}
if (options::EnableBareSlashRegexLiterals) {
InitInvok.getLangOptions().EnableBareSlashRegexLiterals = true;
InitInvok.getLangOptions().Features.insert(Feature::BareSlashRegexLiterals);
InitInvok.getLangOptions().EnableExperimentalStringProcessing = true;
}

Expand Down
2 changes: 1 addition & 1 deletion tools/swift-syntax-test/swift-syntax-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ int parseFile(
Invocation.getLangOptions().VerifySyntaxTree = options::VerifySyntaxTree;
Invocation.getLangOptions().DisablePoundIfEvaluation = true;
Invocation.getLangOptions().EnableExperimentalStringProcessing = true;
Invocation.getLangOptions().EnableBareSlashRegexLiterals = true;
Invocation.getLangOptions().Features.insert(Feature::BareSlashRegexLiterals);

Invocation.getFrontendOptions().InputsAndOutputs.addInputFile(InputFileName);

Expand Down