Enable 'BorrowingSwitch' feature.

This commit is contained in:
Joe Groff
2024-04-10 14:52:59 -07:00
parent c20331b789
commit 10f9289ef8
28 changed files with 70 additions and 113 deletions

View File

@@ -984,7 +984,7 @@ ERROR(extra_var_in_multiple_pattern_list,none,
ERROR(let_pattern_in_immutable_context,none,
"'let' pattern cannot appear nested in an already immutable context", ())
WARNING(borrowing_syntax_change,none,
"'_borrowing' spelling is deprecated; use 'borrowing' without the underscore", ())
"'borrowing' in pattern matches is deprecated; use 'let'", ())
ERROR(borrowing_subpattern_unsupported,none,
"'borrowing' pattern modifier must be directly applied to pattern variable name", ())
ERROR(specifier_must_have_type,none,

View File

@@ -197,6 +197,7 @@ UPCOMING_FEATURE(RegionBasedIsolation, 414, 6)
UPCOMING_FEATURE(DynamicActorIsolation, 423, 6)
UPCOMING_FEATURE(NonfrozenEnumExhaustivity, 192, 6)
UPCOMING_FEATURE(GlobalActorIsolatedTypesUsability, 0434, 6)
UPCOMING_FEATURE(BorrowingSwitch, 432, 6)
// Swift 7
UPCOMING_FEATURE(ExistentialAny, 335, 7)
@@ -354,9 +355,6 @@ EXPERIMENTAL_FEATURE(GroupActorErrors, true)
// Allow for the 'transferring' keyword to be applied to arguments and results.
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(TransferringArgsAndResults, true)
// Allow for `switch` of noncopyable values to be borrowing or consuming.
EXPERIMENTAL_FEATURE(BorrowingSwitch, true)
// Enable explicit isolation of closures.
EXPERIMENTAL_FEATURE(ClosureIsolation, true)

View File

@@ -60,7 +60,6 @@ extension Parser.ExperimentalFeatures {
mapFeature(.DoExpressions, to: .doExpressions)
mapFeature(.NonescapableTypes, to: .nonescapableTypes)
mapFeature(.TransferringArgsAndResults, to: .transferringArgsAndResults)
mapFeature(.BorrowingSwitch, to: .borrowingSwitch)
}
}

View File

@@ -1323,45 +1323,41 @@ ParserResult<Pattern> Parser::parseMatchingPattern(bool isExprBasic) {
// The `borrowing` modifier is a contextual keyword, so it's only accepted
// directly applied to a binding name, as in `case .foo(borrowing x)`.
if (Context.LangOpts.hasFeature(Feature::BorrowingSwitch)) {
if ((Tok.isContextualKeyword("_borrowing")
|| Tok.isContextualKeyword("borrowing"))
&& peekToken().isAny(tok::identifier, tok::kw_self, tok::dollarident,
tok::code_complete)
&& !peekToken().isAtStartOfLine()) {
if (Tok.isContextualKeyword("_borrowing")) {
diagnose(Tok.getLoc(),
diag::borrowing_syntax_change)
.fixItReplace(Tok.getLoc(), "borrowing");
}
if ((Tok.isContextualKeyword("_borrowing")
|| Tok.isContextualKeyword("borrowing"))
&& peekToken().isAny(tok::identifier, tok::kw_self, tok::dollarident,
tok::code_complete)
&& !peekToken().isAtStartOfLine()) {
diagnose(Tok.getLoc(),
diag::borrowing_syntax_change)
.fixItReplace(Tok.getLoc(), "let");
Tok.setKind(tok::contextual_keyword);
SourceLoc borrowingLoc = consumeToken();
// If we have `case borrowing x.`, `x(`, `x[`, or `x<` then this looks
// like an attempt to include a subexpression under a `borrowing`
// binding, which isn't yet supported.
if (peekToken().isAny(tok::period, tok::period_prefix, tok::l_paren,
tok::l_square)
|| (peekToken().isAnyOperator() && peekToken().getText().equals("<"))) {
Tok.setKind(tok::contextual_keyword);
SourceLoc borrowingLoc = consumeToken();
// If we have `case borrowing x.`, `x(`, `x[`, or `x<` then this looks
// like an attempt to include a subexpression under a `borrowing`
// binding, which isn't yet supported.
if (peekToken().isAny(tok::period, tok::period_prefix, tok::l_paren,
tok::l_square)
|| (peekToken().isAnyOperator() && peekToken().getText().equals("<"))) {
// Diagnose the unsupported production.
diagnose(Tok.getLoc(),
diag::borrowing_subpattern_unsupported);
// Recover by parsing as if it was supported.
return parseMatchingPattern(isExprBasic);
}
Identifier name;
SourceLoc nameLoc = consumeIdentifier(name,
/*diagnoseDollarPrefix*/ false);
auto namedPattern = createBindingFromPattern(nameLoc, name,
VarDecl::Introducer::Borrowing);
auto bindPattern = new (Context) BindingPattern(
borrowingLoc, VarDecl::Introducer::Borrowing, namedPattern);
// Diagnose the unsupported production.
diagnose(Tok.getLoc(),
diag::borrowing_subpattern_unsupported);
return makeParserResult(bindPattern);
// Recover by parsing as if it was supported.
return parseMatchingPattern(isExprBasic);
}
Identifier name;
SourceLoc nameLoc = consumeIdentifier(name,
/*diagnoseDollarPrefix*/ false);
auto namedPattern = createBindingFromPattern(nameLoc, name,
VarDecl::Introducer::Borrowing);
auto bindPattern = new (Context) BindingPattern(
borrowingLoc, VarDecl::Introducer::Borrowing, namedPattern);
return makeParserResult(bindPattern);
}
// matching-pattern ::= 'is' type
@@ -1442,14 +1438,12 @@ Parser::parseMatchingPatternAsBinding(PatternBindingState newState,
}
bool Parser::isOnlyStartOfMatchingPattern() {
if (Context.LangOpts.hasFeature(Feature::BorrowingSwitch)) {
if ((Tok.isContextualKeyword("_borrowing")
|| Tok.isContextualKeyword("borrowing"))
&& peekToken().isAny(tok::identifier, tok::kw_self, tok::dollarident,
tok::code_complete)
&& !peekToken().isAtStartOfLine()) {
return true;
}
if ((Tok.isContextualKeyword("_borrowing")
|| Tok.isContextualKeyword("borrowing"))
&& peekToken().isAny(tok::identifier, tok::kw_self, tok::dollarident,
tok::code_complete)
&& !peekToken().isAtStartOfLine()) {
return true;
}
return Tok.isAny(tok::kw_var, tok::kw_let, tok::kw_is) ||

View File

@@ -4575,18 +4575,6 @@ diagnoseMoveOnlyPatternMatchSubject(ASTContext &C,
|| !subjectType->isNoncopyable()) {
return;
}
// A bare reference to, or load from, a move-only binding must be consumed.
subjectExpr = subjectExpr->getSemanticsProvidingExpr();
if (auto load = dyn_cast<LoadExpr>(subjectExpr)) {
subjectExpr = load->getSubExpr()->getSemanticsProvidingExpr();
}
if (!C.LangOpts.hasFeature(Feature::BorrowingSwitch)
&& isa<DeclRefExpr>(subjectExpr)) {
C.Diags.diagnose(subjectExpr->getLoc(),
diag::move_only_pattern_match_not_consumed)
.fixItInsert(subjectExpr->getStartLoc(), "consume ");
}
}
// Perform MiscDiagnostics on Switch Statements.

View File

@@ -315,7 +315,7 @@ list(APPEND swift_stdlib_compile_flags "-Xfrontend" "-enable-experimental-concis
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "Macros")
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "FreestandingMacros")
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "Extern")
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "BorrowingSwitch")
list(APPEND swift_stdlib_compile_flags "-enable-experimental-feature" "BitwiseCopyable")
if("${SWIFT_NATIVE_SWIFT_TOOLS_PATH}" STREQUAL "")
set(swift_bin_dir "${CMAKE_BINARY_DIR}/bin")

View File

@@ -1,13 +1,12 @@
// RUN: %target-swift-emit-irgen \
// RUN: -parse-as-library \
// RUN: -enable-builtin-module \
// RUN: -enable-experimental-feature BorrowingSwitch \
// RUN: %s \
// RUN: | \
// RUN: %FileCheck %s --check-prefix=CHECK-IR
// RUN: %target-run-simple-swift(-parse-as-library -enable-builtin-module -enable-experimental-feature BorrowingSwitch -Xfrontend -sil-verify-all) | %FileCheck %s
// RUN: %target-run-simple-swift(-O -parse-as-library -enable-builtin-module -enable-experimental-feature BorrowingSwitch -Xfrontend -sil-verify-all) | %FileCheck %s
// RUN: %target-run-simple-swift(-O -parse-as-library -enable-builtin-module -enable-experimental-feature BorrowingSwitch -Xfrontend -sil-verify-all -Xfrontend -enable-ossa-modules) | %FileCheck %s
// RUN: %target-run-simple-swift(-parse-as-library -enable-builtin-module -Xfrontend -sil-verify-all) | %FileCheck %s
// RUN: %target-run-simple-swift(-O -parse-as-library -enable-builtin-module -Xfrontend -sil-verify-all) | %FileCheck %s
// RUN: %target-run-simple-swift(-O -parse-as-library -enable-builtin-module -Xfrontend -sil-verify-all -Xfrontend -enable-ossa-modules) | %FileCheck %s
// REQUIRES: executable_test

View File

@@ -6,8 +6,7 @@
// RUN: -module-name Swiftskell \
// RUN: -parse-as-library \
// RUN: %S/../Inputs/Swiftskell.swift -c -o %t/Swiftskell.o \
// RUN: -enable-experimental-feature NonescapableTypes \
// RUN: -enable-experimental-feature BorrowingSwitch
// RUN: -enable-experimental-feature NonescapableTypes
// RUN: %target-build-swift -o %t/a.out %s -I %t %t/Swiftskell.o
// RUN: %target-codesign %t/a.out

View File

@@ -10,7 +10,6 @@
// RUN: %target-swift-frontend -swift-version 5 -enable-library-evolution -emit-module \
// RUN: -enable-experimental-feature SuppressedAssociatedTypes \
// RUN: -enable-experimental-feature NonescapableTypes \
// RUN: -enable-experimental-feature BorrowingSwitch \
// RUN: -o %t/Swiftskell.swiftmodule \
// RUN: -emit-module-interface-path %t/Swiftskell.swiftinterface \
// RUN: %S/../Inputs/Swiftskell.swift

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -enable-experimental-feature BorrowingSwitch -typecheck -verify %s
// RUN: %target-swift-frontend -typecheck -verify %s
struct Payload: ~Copyable {
var x: Int
@@ -38,16 +38,19 @@ func testBorrowingPatterns(bar: borrowing Bar) {
case borrowing (): // parses as `borrowing()` as before
break
case borrowing x:
case borrowing x: // expected-warning{{'borrowing' in pattern matches is deprecated}} {{10-19=let}}
useBorrowBar(x)
case .payload(borrowing x):
case .payload(borrowing x): // expected-warning{{'borrowing' in pattern matches is deprecated}} {{19-28=let}}
useBorrowFoo(x)
case borrowing x.member: // expected-error{{'borrowing' pattern modifier must be directly applied to pattern variable name}} expected-error{{cannot find 'x' in scope}}
case borrowing x.member: // expected-warning{{deprecated}} expected-error{{'borrowing' pattern modifier must be directly applied to pattern variable name}} expected-error{{cannot find 'x' in scope}}
break
case _borrowing x: // expected-warning{{'_borrowing' spelling is deprecated}} {{10-20=borrowing}}
case borrowing x: // expected-warning{{'borrowing' in pattern matches is deprecated}} {{10-19=let}}
useBorrowBar(x)
case _borrowing x: // expected-warning{{'borrowing' in pattern matches is deprecated}} {{10-20=let}}
useBorrowBar(x)
default:

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-emit-silgen -enable-experimental-feature BorrowingSwitch -verify %s
// RUN: %target-swift-emit-silgen -verify %s
func orElse<T: ~Copyable>(
x: consuming T?,
defaultValue: @autoclosure () throws -> T?

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-emit-silgen -enable-experimental-feature BorrowingSwitch -verify %s
// RUN: %target-swift-emit-silgen -verify %s
struct Box<Wrapped: ~Copyable>: ~Copyable {
var wrapped: Wrapped {

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-emit-silgen -enable-experimental-feature BorrowingSwitch %s | %FileCheck %s
// RUN: %target-swift-emit-silgen %s | %FileCheck %s
struct Inner: ~Copyable {}

View File

@@ -1,7 +1,6 @@
// RUN: %target-swift-frontend \
// RUN: -emit-silgen \
// RUN: %s \
// RUN: -enable-experimental-feature BorrowingSwitch \
// RUN: | %FileCheck %s
enum MaybeMaybeVoid<Wrapped: ~Copyable>: ~Copyable {

View File

@@ -2,8 +2,7 @@
// RUN: -verify \
// RUN: -sil-verify-all \
// RUN: -module-name test \
// RUN: -enable-experimental-feature NonescapableTypes \
// RUN: -enable-experimental-feature BorrowingSwitch
// RUN: -enable-experimental-feature NonescapableTypes
// REQUIRES: asserts
// REQUIRES: swift_in_compiler
@@ -58,7 +57,7 @@ extension Nillable where Wrapped: ~Copyable {
_ transform: (borrowing Wrapped) throws(E) -> U
) throws(E) -> U? {
switch self {
case .some(borrowing y):
case .some(let y):
return .some(try transform(y))
case .none:
return .none
@@ -82,7 +81,7 @@ extension Nillable where Wrapped: ~Copyable {
_ transform: (borrowing Wrapped) throws(E) -> U?
) throws(E) -> U? {
switch self {
case .some(borrowing y):
case .some(let y):
return try transform(y)
case .none:
return .none

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-emit-sil %s -O -sil-verify-all -verify -enable-experimental-feature BorrowingSwitch -enable-experimental-feature MoveOnlyPartialReinitialization -enable-experimental-feature NoImplicitCopy -enable-experimental-feature MoveOnlyClasses
// RUN: %target-swift-emit-sil %s -O -sil-verify-all -verify -enable-experimental-feature MoveOnlyPartialReinitialization -enable-experimental-feature NoImplicitCopy -enable-experimental-feature MoveOnlyClasses
//////////////////
// Declarations //

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-sil -verify -enable-experimental-feature BorrowingSwitch %s
// RUN: %target-swift-frontend -emit-sil -verify %s
struct Payload: ~Copyable {
var x: Int

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-sil -verify -enable-experimental-feature BorrowingSwitch %s
// RUN: %target-swift-frontend -emit-sil -verify %s
struct Payload: ~Copyable {
var x: Int
@@ -31,25 +31,7 @@ func test(borrowing foo: borrowing Foo) {
eat(x)
nibble(x)
// `borrowing` match variables impose the no-implicit-copy constraint
// like `borrowing` parameters do.
case .copyablePayload(borrowing x) // expected-error{{'x' is borrowed and cannot be consumed}}
where hungryCondition(x): // expected-note{{consumed here}}
eat(x) // expected-note{{consumed here}}
nibble(x)
case .copyablePayload(borrowing x) // expected-error{{'x' is borrowed and cannot be consumed}}
where condition(x):
eat(x) // expected-note{{consumed here}}
nibble(x)
// Explicit copies are OK.
case .copyablePayload(borrowing x)
where hungryCondition(copy x):
eat(copy x)
nibble(x)
case .copyablePayload(borrowing x):
case .copyablePayload(let x):
nibble(x)
}
}

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -enable-experimental-feature BorrowingSwitch -emit-sil -verify %s
// RUN: %target-swift-frontend -emit-sil -verify %s
struct Box<Wrapped: ~Copyable>: ~Copyable {
init(_ element: consuming Wrapped) { }

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-sil -verify -enable-experimental-feature BorrowingSwitch -parse-as-library %s
// RUN: %target-swift-frontend -emit-sil -verify -parse-as-library %s
func foo() {
let node = Node()

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -enable-experimental-feature BorrowingSwitch -parse-as-library -O -emit-sil -verify %s
// RUN: %target-swift-frontend -parse-as-library -O -emit-sil -verify %s
extension List {
var peek: Element {

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-sil -enable-experimental-feature BorrowingSwitch -verify %s
// RUN: %target-swift-frontend -emit-sil -verify %s
// TODO: Remove this and just use the real `UnsafeMutablePointer` when
// noncopyable type support has been upstreamed.

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -emit-sil -enable-experimental-feature BorrowingSwitch -verify %s
// RUN: %target-swift-frontend -emit-sil -verify %s
struct Box: ~Copyable {
let ptr: UnsafeMutablePointer<Int>

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-emit-sil -enable-experimental-feature BorrowingSwitch -sil-verify-all -verify -enable-experimental-feature MoveOnlyClasses %s
// RUN: %target-swift-emit-sil -sil-verify-all -verify -enable-experimental-feature MoveOnlyClasses %s
//////////////////
// Declarations //

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-emit-sil -enable-experimental-feature BorrowingSwitch -enable-experimental-feature MoveOnlyPartialReinitialization -sil-verify-all -verify %s
// RUN: %target-swift-emit-sil -enable-experimental-feature MoveOnlyPartialReinitialization -sil-verify-all -verify %s
//////////////////
// Declarations //

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-emit-sil -enable-experimental-feature BorrowingSwitch -sil-verify-all -verify %s
// RUN: %target-swift-emit-sil -sil-verify-all -verify %s
//////////////////
// Declarations //

View File

@@ -1,7 +1,6 @@
// RUN: %target-swift-emit-ir \
// RUN: %s \
// RUN: -enable-builtin-module \
// RUN: -enable-experimental-feature BorrowingSwitch \
// RUN: -sil-verify-all \
// RUN: -verify

View File

@@ -1,7 +1,6 @@
// RUN: %target-swift-emit-sil \
// RUN: %s \
// RUN: -enable-builtin-module \
// RUN: -enable-experimental-feature BorrowingSwitch \
// RUN: -sil-verify-all \
// RUN: -verify