Skip to content

Commit b844711

Browse files
Merge pull request #4613 from swiftwasm/main
[pull] swiftwasm from main
2 parents 0af0ebf + a6ffb09 commit b844711

File tree

16 files changed

+246
-114
lines changed

16 files changed

+246
-114
lines changed

include/swift/Basic/Feature.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef SWIFT_BASIC_FEATURES_H
1414
#define SWIFT_BASIC_FEATURES_H
1515

16+
#include "llvm/ADT/Optional.h"
1617
#include "llvm/ADT/StringRef.h"
1718

1819
namespace swift {
@@ -51,10 +52,17 @@ inline bool featureImpliesFeature(Feature feature, Feature implied) {
5152
return (unsigned) feature < (unsigned) implied;
5253
}
5354

55+
/// Get the feature corresponding to this "future" feature, if there is one.
56+
llvm::Optional<Feature> getFutureFeature(llvm::StringRef name);
57+
5458
/// Get the feature corresponding to this "experimental" feature, if there is
5559
/// one.
5660
llvm::Optional<Feature> getExperimentalFeature(llvm::StringRef name);
5761

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

6068
#endif // SWIFT_BASIC_FEATURES_H

include/swift/Basic/Features.def

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

51+
#ifndef FUTURE_FEATURE
52+
# define FUTURE_FEATURE(FeatureName, SENumber, Version) \
53+
LANGUAGE_FEATURE(FeatureName, SENumber, #FeatureName, \
54+
langOpts.hasFeature(#FeatureName))
55+
#endif
56+
5157
#ifndef EXPERIMENTAL_FEATURE
5258
# define EXPERIMENTAL_FEATURE(FeatureName) \
5359
LANGUAGE_FEATURE(FeatureName, 0, #FeatureName, \
@@ -83,6 +89,10 @@ SUPPRESSIBLE_LANGUAGE_FEATURE(PrimaryAssociatedTypes2, 346, "Primary associated
8389
SUPPRESSIBLE_LANGUAGE_FEATURE(UnavailableFromAsync, 0, "@_unavailableFromAsync", true)
8490
SUPPRESSIBLE_LANGUAGE_FEATURE(NoAsyncAvailability, 340, "@available(*, noasync)", true)
8591

92+
FUTURE_FEATURE(ConciseMagicFile, 274, 6)
93+
FUTURE_FEATURE(ForwardTrailingClosures, 286, 6)
94+
FUTURE_FEATURE(BareSlashRegexLiterals, 354, 6)
95+
8696
EXPERIMENTAL_FEATURE(StaticAssert)
8797
EXPERIMENTAL_FEATURE(VariadicGenerics)
8898
EXPERIMENTAL_FEATURE(NamedOpaqueTypes)
@@ -92,5 +102,6 @@ EXPERIMENTAL_FEATURE(OneWayClosureParameters)
92102
EXPERIMENTAL_FEATURE(TypeWitnessSystemInference)
93103

94104
#undef EXPERIMENTAL_FEATURE
105+
#undef FUTURE_FEATURE
95106
#undef SUPPRESSIBLE_LANGUAGE_FEATURE
96107
#undef LANGUAGE_FEATURE

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@ namespace swift {
354354
/// The set of features that have been enabled.
355355
llvm::SmallSet<Feature, 2> Features;
356356

357+
/// Temporary flag to support LLDB's transition to using \c Features.
358+
bool EnableBareSlashRegexLiterals = false;
359+
357360
/// Use Clang function types for computing canonical types.
358361
/// If this option is false, the clang function types will still be computed
359362
/// but will not be used for checking type equality.
@@ -529,10 +532,6 @@ namespace swift {
529532
/// Enables dumping type witness systems from associated type inference.
530533
bool DumpTypeWitnessSystems = false;
531534

532-
/// Enables `/.../` syntax regular-expression literals. This requires
533-
/// experimental string processing. Note this does not affect `#/.../#`.
534-
bool EnableBareSlashRegexLiterals = false;
535-
536535
/// Sets the target we are building for and updates platform conditions
537536
/// to match.
538537
///

lib/AST/ASTPrinter.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2999,6 +2999,18 @@ static bool usesFeatureNoAsyncAvailability(Decl *decl) {
29992999
return decl->getAttrs().getNoAsync(decl->getASTContext()) != nullptr;
30003000
}
30013001

3002+
static bool usesFeatureConciseMagicFile(Decl *decl) {
3003+
return false;
3004+
}
3005+
3006+
static bool usesFeatureForwardTrailingClosures(Decl *decl) {
3007+
return false;
3008+
}
3009+
3010+
static bool usesFeatureBareSlashRegexLiterals(Decl *decl) {
3011+
return false;
3012+
}
3013+
30023014
static bool usesFeatureVariadicGenerics(Decl *decl) {
30033015
return false;
30043016
}

lib/Basic/LangOptions.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "swift/Config.h"
2424
#include "llvm/ADT/Hashing.h"
2525
#include "llvm/ADT/SmallString.h"
26+
#include "llvm/ADT/StringSwitch.h"
2627
#include "llvm/Support/raw_ostream.h"
2728
#include <limits.h>
2829

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

232+
if (feature == Feature::BareSlashRegexLiterals &&
233+
EnableBareSlashRegexLiterals)
234+
return true;
235+
236+
if (auto version = getFeatureLanguageVersion(feature))
237+
return isSwiftVersionAtLeast(*version);
238+
231239
return false;
232240
}
233241

234242
bool LangOptions::hasFeature(llvm::StringRef featureName) const {
243+
if (auto feature = getFutureFeature(featureName))
244+
return hasFeature(*feature);
245+
235246
if (auto feature = getExperimentalFeature(featureName))
236247
return hasFeature(*feature);
237248

@@ -423,6 +434,15 @@ bool swift::isSuppressibleFeature(Feature feature) {
423434
llvm_unreachable("covered switch");
424435
}
425436

437+
llvm::Optional<Feature> swift::getFutureFeature(llvm::StringRef name) {
438+
return llvm::StringSwitch<Optional<Feature>>(name)
439+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option)
440+
#define FUTURE_FEATURE(FeatureName, SENumber, Version) \
441+
.Case(#FeatureName, Feature::FeatureName)
442+
#include "swift/Basic/Features.def"
443+
.Default(None);
444+
}
445+
426446
llvm::Optional<Feature> swift::getExperimentalFeature(llvm::StringRef name) {
427447
return llvm::StringSwitch<Optional<Feature>>(name)
428448
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option)
@@ -432,6 +452,16 @@ llvm::Optional<Feature> swift::getExperimentalFeature(llvm::StringRef name) {
432452
.Default(None);
433453
}
434454

455+
llvm::Optional<unsigned> swift::getFeatureLanguageVersion(Feature feature) {
456+
switch (feature) {
457+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option)
458+
#define FUTURE_FEATURE(FeatureName, SENumber, Version) \
459+
case Feature::FeatureName: return Version;
460+
#include "swift/Basic/Features.def"
461+
default: return None;
462+
}
463+
}
464+
435465
DiagnosticBehavior LangOptions::getAccessNoteFailureLimit() const {
436466
switch (AccessNoteBehavior) {
437467
case AccessNoteDiagnosticBehavior::Ignore:

lib/Frontend/CompilerInvocation.cpp

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -486,25 +486,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
486486
= A->getOption().matches(OPT_enable_deserialization_recovery);
487487
}
488488

489-
// Whether '/.../' regex literals are enabled. This implies experimental
490-
// string processing.
491-
if (Args.hasArg(OPT_enable_bare_slash_regex)) {
492-
Opts.EnableBareSlashRegexLiterals = true;
493-
Opts.EnableExperimentalStringProcessing = true;
494-
}
495-
496-
// Experimental string processing.
497-
if (auto A = Args.getLastArg(OPT_enable_experimental_string_processing,
498-
OPT_disable_experimental_string_processing)) {
499-
Opts.EnableExperimentalStringProcessing =
500-
A->getOption().matches(OPT_enable_experimental_string_processing);
501-
502-
// When experimental string processing is explicitly disabled, also disable
503-
// forward slash regex `/.../`.
504-
if (!Opts.EnableExperimentalStringProcessing)
505-
Opts.EnableBareSlashRegexLiterals = false;
506-
}
507-
508489
Opts.EnableExperimentalBoundGenericExtensions |=
509490
Args.hasArg(OPT_enable_experimental_bound_generic_extensions);
510491

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

616+
// Determine whether string processing is enabled
617+
Opts.EnableExperimentalStringProcessing =
618+
Args.hasFlag(OPT_enable_experimental_string_processing,
619+
OPT_disable_experimental_string_processing,
620+
Args.hasArg(OPT_enable_bare_slash_regex));
621+
622+
// Add a future feature if it is not already implied by the language version.
623+
auto addFutureFeatureIfNotImplied = [&](Feature feature) {
624+
// Check if this feature was introduced already in this language version.
625+
if (auto firstVersion = getFeatureLanguageVersion(feature)) {
626+
if (Opts.isSwiftVersionAtLeast(*firstVersion))
627+
return;
628+
}
629+
630+
Opts.Features.insert(feature);
631+
};
632+
633+
// Map historical flags over to future features.
634+
if (Args.hasArg(OPT_enable_experimental_concise_pound_file))
635+
addFutureFeatureIfNotImplied(Feature::ConciseMagicFile);
636+
if (Args.hasArg(OPT_enable_bare_slash_regex))
637+
addFutureFeatureIfNotImplied(Feature::BareSlashRegexLiterals);
638+
635639
for (const Arg *A : Args.filtered(OPT_enable_experimental_feature)) {
636640
// If this is a known experimental feature, allow it in +Asserts
637641
// (non-release) builds for testing purposes.
@@ -759,10 +763,6 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
759763
A->getAsString(Args), A->getValue());
760764
}
761765

762-
Opts.EnableConcisePoundFile =
763-
Args.hasArg(OPT_enable_experimental_concise_pound_file) ||
764-
Opts.EffectiveLanguageVersion.isVersionAtLeast(6);
765-
766766
Opts.EnableCrossImportOverlays =
767767
Args.hasFlag(OPT_enable_cross_import_overlays,
768768
OPT_disable_cross_import_overlays,

lib/Parse/ParseExpr.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -881,7 +881,8 @@ UnresolvedDeclRefExpr *Parser::parseExprOperator() {
881881
}
882882

883883
void Parser::tryLexRegexLiteral(bool forUnappliedOperator) {
884-
if (!Context.LangOpts.EnableBareSlashRegexLiterals)
884+
if (!Context.LangOpts.hasFeature(Feature::BareSlashRegexLiterals) ||
885+
!Context.LangOpts.EnableExperimentalStringProcessing)
885886
return;
886887

887888
// Check to see if we have a regex literal `/.../`, optionally with a prefix
@@ -1114,7 +1115,7 @@ getMagicIdentifierLiteralKind(tok Kind, const LangOptions &Opts) {
11141115
switch (Kind) {
11151116
case tok::pound_file:
11161117
// TODO: Enable by default at the next source break. (SR-13199)
1117-
return Opts.EnableConcisePoundFile
1118+
return Opts.hasFeature(Feature::ConciseMagicFile)
11181119
? MagicIdentifierLiteralExpr::FileIDSpelledAsFile
11191120
: MagicIdentifierLiteralExpr::FilePathSpelledAsFile;
11201121
#define MAGIC_IDENTIFIER_TOKEN(NAME, TOKEN) \

lib/Sema/CSClosure.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,17 @@ class SyntacticElementSolutionApplication
12081208
return nullptr;
12091209
}
12101210

1211+
ASTNode visit(Stmt *S) {
1212+
auto rewritten = ASTVisitor::visit(S);
1213+
if (!rewritten)
1214+
return {};
1215+
1216+
if (auto *stmt = getAsStmt(rewritten))
1217+
performStmtDiagnostics(stmt, context.getAsDeclContext());
1218+
1219+
return rewritten;
1220+
}
1221+
12111222
void visitDecl(Decl *decl) {
12121223
if (isa<IfConfigDecl>(decl))
12131224
return;

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ static bool matchCallArgumentsImpl(
472472
// way to successfully match arguments to parameters.
473473
if (!parameterRequiresArgument(params, paramInfo, paramIdx) &&
474474
!param.getPlainType()->getASTContext().LangOpts
475-
.isSwiftVersionAtLeast(6) &&
475+
.hasFeature(Feature::ForwardTrailingClosures) &&
476476
anyParameterRequiresArgument(
477477
params, paramInfo, paramIdx + 1,
478478
nextArgIdx + 1 < numArgs
@@ -934,7 +934,7 @@ static bool requiresBothTrailingClosureDirections(
934934

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

940940
// If there are at least two parameters that meet the backward scan's

test/Syntax/Parser/unterminated_regex.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %swift-syntax-parser-test -dump-diags %s | %FileCheck %s
1+
// RUN: %swift-syntax-parser-test -dump-diags --swift-version 5 --enable-bare-slash-regex %s | %FileCheck %s
22
// CHECK: 6:21 Error: unterminated regex literal
33
// CHECK: 1 error(s) 0 warnings(s) 0 note(s)
44

test/expr/closure/multi_statement.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,36 @@ func test_type_finder_doesnt_walk_into_inner_closures() {
405405
}
406406
}
407407

408+
// rdar://94049113 - compiler accepts non-optional `guard let` in a closure
409+
func test_non_optional_guard_let_is_diagnosed() {
410+
func fn(_: (Int) -> Void) {}
411+
412+
fn {
413+
if true {
414+
guard let v = $0 else { // expected-error {{initializer for conditional binding must have Optional type, not 'Int'}}
415+
return
416+
}
417+
418+
print(v)
419+
}
420+
}
421+
422+
fn {
423+
switch $0 {
424+
case (let val):
425+
fn {
426+
guard let x = val else { // expected-error {{initializer for conditional binding must have Optional type, not 'Int'}}
427+
return
428+
}
429+
430+
print($0 + x)
431+
}
432+
433+
default: break
434+
}
435+
}
436+
}
437+
408438
// rdar://93796211 (issue#59035) - crash during solution application to fallthrough statement
409439
func test_fallthrough_stmt() {
410440
{

tools/libSwiftSyntaxParser/libSwiftSyntaxParser.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -512,9 +512,7 @@ swiftparse_client_node_t SynParser::parse(const char *source, size_t len) {
512512

513513
// Always enable bare /.../ regex literal in syntax parser.
514514
langOpts.EnableExperimentalStringProcessing = true;
515-
if (EnableBareSlashRegexLiteral && *EnableBareSlashRegexLiteral) {
516-
langOpts.EnableBareSlashRegexLiterals = true;
517-
}
515+
langOpts.Features.insert(Feature::BareSlashRegexLiterals);
518516
if (EffectiveLanguageVersion) {
519517
langOpts.EffectiveLanguageVersion = *EffectiveLanguageVersion;
520518
}

tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4305,7 +4305,7 @@ int main(int argc, char *argv[]) {
43054305
InitInvok.getLangOptions().EnableExperimentalStringProcessing = true;
43064306
}
43074307
if (options::EnableBareSlashRegexLiterals) {
4308-
InitInvok.getLangOptions().EnableBareSlashRegexLiterals = true;
4308+
InitInvok.getLangOptions().Features.insert(Feature::BareSlashRegexLiterals);
43094309
InitInvok.getLangOptions().EnableExperimentalStringProcessing = true;
43104310
}
43114311

0 commit comments

Comments
 (0)