diff --git a/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift b/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift index d807c71c00d..a62d4224a60 100644 --- a/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift +++ b/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift @@ -22,6 +22,7 @@ public enum ExperimentalFeature: String, CaseIterable { case valueGenerics case abiAttribute case keypathWithMethodMembers + case oldOwnershipOperatorSpellings /// The name of the feature as it is written in the compiler's `Features.def` file. public var featureName: String { @@ -44,6 +45,8 @@ public enum ExperimentalFeature: String, CaseIterable { return "ABIAttribute" case .keypathWithMethodMembers: return "KeypathWithMethodMembers" + case .oldOwnershipOperatorSpellings: + return "OldOwnershipOperatorSpellings" } } @@ -68,6 +71,8 @@ public enum ExperimentalFeature: String, CaseIterable { return "@abi attribute" case .keypathWithMethodMembers: return "keypaths with method members" + case .oldOwnershipOperatorSpellings: + return "`_move` and `_borrow` as ownership operators" } } diff --git a/Sources/SwiftParser/Expressions.swift b/Sources/SwiftParser/Expressions.swift index ee101e60fcd..1aad77b9558 100644 --- a/Sources/SwiftParser/Expressions.swift +++ b/Sources/SwiftParser/Expressions.swift @@ -481,20 +481,9 @@ extension Parser { arena: self.arena ) ) - case (._move, let handle)?: - let moveKeyword = self.eat(handle) - let sub = self.parseSequenceExpressionElement( - flavor: flavor, - pattern: pattern - ) - return RawExprSyntax( - RawConsumeExprSyntax( - consumeKeyword: moveKeyword, - expression: sub, - arena: self.arena - ) - ) + case (._borrow, let handle)?: + assert(self.experimentalFeatures.contains(.oldOwnershipOperatorSpellings)) fallthrough case (.borrow, let handle)?: if !atContextualExpressionModifier() { @@ -531,6 +520,9 @@ extension Parser { ) ) + case (._move, let handle)?: + assert(self.experimentalFeatures.contains(.oldOwnershipOperatorSpellings)) + fallthrough case (.consume, let handle)?: if !atContextualExpressionModifier() { break EXPR_PREFIX diff --git a/Sources/SwiftParser/TokenSpecSet.swift b/Sources/SwiftParser/TokenSpecSet.swift index 2519b689246..164149d2131 100644 --- a/Sources/SwiftParser/TokenSpecSet.swift +++ b/Sources/SwiftParser/TokenSpecSet.swift @@ -705,8 +705,8 @@ enum ExpressionModifierKeyword: TokenSpecSet { init?(lexeme: Lexer.Lexeme, experimentalFeatures: Parser.ExperimentalFeatures) { switch PrepareForKeywordMatch(lexeme) { case TokenSpec(.await): self = .await - case TokenSpec(._move): self = ._move - case TokenSpec(._borrow): self = ._borrow + case TokenSpec(._move) where experimentalFeatures.contains(.oldOwnershipOperatorSpellings): self = ._move + case TokenSpec(._borrow) where experimentalFeatures.contains(.oldOwnershipOperatorSpellings): self = ._borrow case TokenSpec(.try): self = .try case TokenSpec(.borrow): self = .borrow case TokenSpec(.consume): self = .consume diff --git a/Sources/SwiftParser/generated/ExperimentalFeatures.swift b/Sources/SwiftParser/generated/ExperimentalFeatures.swift index fac23f47224..40d3939c216 100644 --- a/Sources/SwiftParser/generated/ExperimentalFeatures.swift +++ b/Sources/SwiftParser/generated/ExperimentalFeatures.swift @@ -52,6 +52,9 @@ extension Parser.ExperimentalFeatures { /// Whether to enable the parsing of keypaths with method members. public static let keypathWithMethodMembers = Self (rawValue: 1 << 8) + /// Whether to enable the parsing of `_move` and `_borrow` as ownership operators. + public static let oldOwnershipOperatorSpellings = Self (rawValue: 1 << 9) + /// Creates a new value representing the experimental feature with the /// given name, or returns nil if the name is not recognized. public init?(name: String) { @@ -74,6 +77,8 @@ extension Parser.ExperimentalFeatures { self = .abiAttribute case "KeypathWithMethodMembers": self = .keypathWithMethodMembers + case "OldOwnershipOperatorSpellings": + self = .oldOwnershipOperatorSpellings default: return nil } diff --git a/Tests/SwiftParserTest/ExpressionTests.swift b/Tests/SwiftParserTest/ExpressionTests.swift index 8084f19bee4..e63d753d2da 100644 --- a/Tests/SwiftParserTest/ExpressionTests.swift +++ b/Tests/SwiftParserTest/ExpressionTests.swift @@ -1557,18 +1557,18 @@ final class ExpressionTests: ParserTestCase { ) } - func testMoveExpression() { - assertParse("_move msg") - assertParse("use(_move msg)") - assertParse("_move msg") - assertParse("let b = (_move self).buffer") + func testConsumeExpression() { + assertParse("consume msg") + assertParse("use(consume msg)") + assertParse("consume msg") + assertParse("let b = (consume self).buffer") } func testBorrowExpression() { - assertParse("_borrow msg") - assertParse("use(_borrow msg)") - assertParse("_borrow msg") - assertParse("let b = (_borrow self).buffer") + assertParse("borrow msg") + assertParse("use(borrow msg)") + assertParse("borrow msg") + assertParse("let b = (borrow self).buffer") assertParse("borrow msg") assertParse("use(borrow msg)") assertParse("borrow(msg)") diff --git a/Tests/SwiftParserTest/translated/BorrowExprTests.swift b/Tests/SwiftParserTest/translated/BorrowExprTests.swift index 78d07b056c5..d945782a11b 100644 --- a/Tests/SwiftParserTest/translated/BorrowExprTests.swift +++ b/Tests/SwiftParserTest/translated/BorrowExprTests.swift @@ -12,6 +12,8 @@ // This test file has been translated from swift/test/Parse/borrow_expr.swift +@_spi(ExperimentalLanguageFeatures) import SwiftParser +import SwiftSyntax import XCTest final class BorrowExprTests: ParserTestCase { @@ -23,7 +25,8 @@ final class BorrowExprTests: ParserTestCase { func testGlobal() { useString(_borrow global) } - """ + """, + experimentalFeatures: [.oldOwnershipOperatorSpellings] ) } @@ -36,7 +39,8 @@ final class BorrowExprTests: ParserTestCase { t = String() useString(_borrow t) } - """ + """, + experimentalFeatures: [.oldOwnershipOperatorSpellings] ) } diff --git a/Tests/SwiftParserTest/translated/MoveExprTests.swift b/Tests/SwiftParserTest/translated/MoveExprTests.swift index 98d5ad82b76..18f1bb7e135 100644 --- a/Tests/SwiftParserTest/translated/MoveExprTests.swift +++ b/Tests/SwiftParserTest/translated/MoveExprTests.swift @@ -12,6 +12,8 @@ // This test file has been translated from swift/test/Parse/move_expr.swift +@_spi(ExperimentalLanguageFeatures) import SwiftParser +import SwiftSyntax import XCTest final class MoveExprTests: ParserTestCase { @@ -22,7 +24,8 @@ final class MoveExprTests: ParserTestCase { func testGlobal() { let _ = _move global } - """ + """, + experimentalFeatures: [.oldOwnershipOperatorSpellings] ) } @@ -33,7 +36,9 @@ final class MoveExprTests: ParserTestCase { let t = String() let _ = _move t } - """ + """, + experimentalFeatures: [.oldOwnershipOperatorSpellings] + ) } @@ -45,7 +50,58 @@ final class MoveExprTests: ParserTestCase { t = String() let _ = _move t } + """, + experimentalFeatures: [.oldOwnershipOperatorSpellings] + ) + } + + func testMoveExpr4() { + assertParse( + """ + _move(t) + """, + substructure: FunctionCallExprSyntax( + calledExpression: DeclReferenceExprSyntax(baseName: .identifier("_move")), + leftParen: .leftParenToken(), + arguments: [.init(expression: DeclReferenceExprSyntax(baseName: .identifier("t")))], + rightParen: .rightParenToken() + ), + experimentalFeatures: [.oldOwnershipOperatorSpellings] + ) + } + + func testMoveExpr5() { + assertParse( + """ + _move(t) + """, + substructure: FunctionCallExprSyntax( + calledExpression: DeclReferenceExprSyntax(baseName: .identifier("_move")), + leftParen: .leftParenToken(), + arguments: [.init(expression: DeclReferenceExprSyntax(baseName: .identifier("t")))], + rightParen: .rightParenToken() + ), + experimentalFeatures: [] + ) + } + + func testMoveExpr6() { + assertParse( """ + _move1️⃣ t + """, + diagnostics: [ + DiagnosticSpec( + message: "consecutive statements on a line must be separated by newline or ';'", + fixIts: ["insert newline", "insert ';'"] + ) + ], + fixedSource: + """ + _move + t + """, + experimentalFeatures: [] ) }