diff --git a/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift b/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift index b11a846279d..5dca064e5d3 100644 --- a/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift @@ -472,6 +472,7 @@ public let DECL_NODES: [Node] = [ .keyword(.transferring), .keyword(.unowned), .keyword(.weak), + .keyword(.sending), ]) ), Child( diff --git a/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift b/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift index c1ad5793fed..593732ea2a1 100644 --- a/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift +++ b/CodeGeneration/Sources/SyntaxSupport/ExperimentalFeatures.swift @@ -19,6 +19,7 @@ public enum ExperimentalFeature: String, CaseIterable { case nonescapableTypes case transferringArgsAndResults case borrowingSwitch + case sendingArgsAndResults /// The name of the feature, which is used in the doc comment. public var featureName: String { @@ -35,6 +36,8 @@ public enum ExperimentalFeature: String, CaseIterable { return "TransferringArgsAndResults" case .borrowingSwitch: return "borrowing pattern matching" + case .sendingArgsAndResults: + return "SendingArgsAndResults" } } diff --git a/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift b/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift index d73b8afe6c4..9b3ec7292d0 100644 --- a/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift +++ b/CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift @@ -263,6 +263,7 @@ public enum Keyword: CaseIterable { case safe case scoped case `self` + case sending case `Self` case Sendable case set @@ -701,6 +702,11 @@ public enum Keyword: CaseIterable { "transferring", experimentalFeature: .transferringArgsAndResults ) + case .sending: + return KeywordSpec( + "sending", + experimentalFeature: .sendingArgsAndResults + ) case .transpose: return KeywordSpec("transpose") case .true: diff --git a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift index f89ddb531d9..93a0740043d 100644 --- a/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift +++ b/CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift @@ -593,6 +593,7 @@ public let TYPE_NODES: [Node] = [ .keyword(.consuming), .keyword(.transferring), .keyword(._resultDependsOn), + .keyword(.sending), ]), documentation: "The specifier token that's attached to the type." ) diff --git a/Sources/SwiftParser/Declarations.swift b/Sources/SwiftParser/Declarations.swift index e8ede5981d4..32d85a93fee 100644 --- a/Sources/SwiftParser/Declarations.swift +++ b/Sources/SwiftParser/Declarations.swift @@ -23,7 +23,7 @@ extension DeclarationModifier { .borrowing, .class, .consuming, .convenience, .distributed, .dynamic, .final, .indirect, .infix, .isolated, .lazy, .mutating, .nonmutating, .optional, .override, .postfix, .prefix, .reasync, ._resultDependsOn, ._resultDependsOnSelf, .required, - .rethrows, .static, .weak, .transferring: + .rethrows, .static, .weak, .transferring, .sending: return false case .fileprivate, .internal, .nonisolated, .package, .open, .private, .public, .unowned: diff --git a/Sources/SwiftParser/Patterns.swift b/Sources/SwiftParser/Patterns.swift index 3764f643594..1adb1c095e6 100644 --- a/Sources/SwiftParser/Patterns.swift +++ b/Sources/SwiftParser/Patterns.swift @@ -378,6 +378,7 @@ extension Parser.Lookahead { && !self.at(.keyword(.borrowing)) && !self.at(.keyword(.consuming)) && !(experimentalFeatures.contains(.transferringArgsAndResults) && self.at(.keyword(.transferring))) + && !(experimentalFeatures.contains(.sendingArgsAndResults) && self.at(.keyword(.sending))) && !(experimentalFeatures.contains(.nonescapableTypes) && self.at(.keyword(._resultDependsOn))) { return true diff --git a/Sources/SwiftParser/TokenPrecedence.swift b/Sources/SwiftParser/TokenPrecedence.swift index e60f5657790..fa80dc81a31 100644 --- a/Sources/SwiftParser/TokenPrecedence.swift +++ b/Sources/SwiftParser/TokenPrecedence.swift @@ -237,7 +237,7 @@ enum TokenPrecedence: Comparable { .__setter_access, .indirect, .isolated, .nonisolated, .distributed, ._local, .inout, ._mutating, ._borrow, ._borrowing, .borrowing, ._consuming, .consuming, .consume, ._resultDependsOnSelf, ._resultDependsOn, - .transferring, .dependsOn, .scoped, + .transferring, .dependsOn, .scoped, .sending, // Accessors .get, .set, .didSet, .willSet, .unsafeAddress, .addressWithOwner, .addressWithNativeOwner, .unsafeMutableAddress, .mutableAddressWithOwner, .mutableAddressWithNativeOwner, ._read, ._modify, diff --git a/Sources/SwiftParser/TokenSpecSet.swift b/Sources/SwiftParser/TokenSpecSet.swift index 2dd8034cb11..694cb5f8ae8 100644 --- a/Sources/SwiftParser/TokenSpecSet.swift +++ b/Sources/SwiftParser/TokenSpecSet.swift @@ -377,6 +377,7 @@ enum DeclarationModifier: TokenSpecSet { case reasync case required case `rethrows` + case sending case `static` case transferring case unowned @@ -420,6 +421,7 @@ enum DeclarationModifier: TokenSpecSet { case TokenSpec(.rethrows): self = .rethrows case TokenSpec(.static): self = .static case TokenSpec(.transferring): self = .transferring + case TokenSpec(.sending): self = .sending case TokenSpec(.unowned): self = .unowned case TokenSpec(.weak): self = .weak case TokenSpec(._resultDependsOn) where experimentalFeatures.contains(.nonescapableTypes): self = ._resultDependsOn @@ -465,6 +467,7 @@ enum DeclarationModifier: TokenSpecSet { case .rethrows: return TokenSpec(.rethrows, recoveryPrecedence: .declKeyword) case .static: return .keyword(.static) case .transferring: return .keyword(.transferring) + case .sending: return .keyword(.sending) case .unowned: return TokenSpec(.unowned, recoveryPrecedence: .declKeyword) case .weak: return TokenSpec(.weak, recoveryPrecedence: .declKeyword) case ._resultDependsOn: return TokenSpec(._resultDependsOn, recoveryPrecedence: .declKeyword) diff --git a/Sources/SwiftParser/generated/ExperimentalFeatures.swift b/Sources/SwiftParser/generated/ExperimentalFeatures.swift index 6fae76a97a2..b2bd8f08f84 100644 --- a/Sources/SwiftParser/generated/ExperimentalFeatures.swift +++ b/Sources/SwiftParser/generated/ExperimentalFeatures.swift @@ -41,4 +41,7 @@ extension Parser.ExperimentalFeatures { /// Whether to enable the parsing of borrowing pattern matching. public static let borrowingSwitch = Self (rawValue: 1 << 5) + + /// Whether to enable the parsing of SendingArgsAndResults. + public static let sendingArgsAndResults = Self (rawValue: 1 << 6) } diff --git a/Sources/SwiftParser/generated/Parser+TokenSpecSet.swift b/Sources/SwiftParser/generated/Parser+TokenSpecSet.swift index 5221e05d41e..b23408afece 100644 --- a/Sources/SwiftParser/generated/Parser+TokenSpecSet.swift +++ b/Sources/SwiftParser/generated/Parser+TokenSpecSet.swift @@ -814,6 +814,10 @@ extension DeclModifierSyntax { case transferring case unowned case weak + #if compiler(>=5.8) + @_spi(ExperimentalLanguageFeatures) + #endif + case sending init?(lexeme: Lexer.Lexeme, experimentalFeatures: Parser.ExperimentalFeatures) { switch PrepareForKeywordMatch(lexeme) { @@ -891,6 +895,8 @@ extension DeclModifierSyntax { self = .unowned case TokenSpec(.weak): self = .weak + case TokenSpec(.sending) where experimentalFeatures.contains(.sendingArgsAndResults): + self = .sending default: return nil } @@ -972,6 +978,8 @@ extension DeclModifierSyntax { self = .unowned case TokenSpec(.weak): self = .weak + case TokenSpec(.sending): + self = .sending default: return nil } @@ -1053,6 +1061,8 @@ extension DeclModifierSyntax { return .keyword(.unowned) case .weak: return .keyword(.weak) + case .sending: + return .keyword(.sending) } } @@ -1136,6 +1146,8 @@ extension DeclModifierSyntax { return .keyword(.unowned) case .weak: return .keyword(.weak) + case .sending: + return .keyword(.sending) } } } @@ -3347,6 +3359,10 @@ extension SimpleTypeSpecifierSyntax { @_spi(ExperimentalLanguageFeatures) #endif case _resultDependsOn + #if compiler(>=5.8) + @_spi(ExperimentalLanguageFeatures) + #endif + case sending init?(lexeme: Lexer.Lexeme, experimentalFeatures: Parser.ExperimentalFeatures) { switch PrepareForKeywordMatch(lexeme) { @@ -3368,6 +3384,8 @@ extension SimpleTypeSpecifierSyntax { self = .transferring case TokenSpec(._resultDependsOn) where experimentalFeatures.contains(.nonescapableTypes): self = ._resultDependsOn + case TokenSpec(.sending) where experimentalFeatures.contains(.sendingArgsAndResults): + self = .sending default: return nil } @@ -3393,6 +3411,8 @@ extension SimpleTypeSpecifierSyntax { self = .transferring case TokenSpec(._resultDependsOn): self = ._resultDependsOn + case TokenSpec(.sending): + self = .sending default: return nil } @@ -3418,6 +3438,8 @@ extension SimpleTypeSpecifierSyntax { return .keyword(.transferring) case ._resultDependsOn: return .keyword(._resultDependsOn) + case .sending: + return .keyword(.sending) } } @@ -3445,6 +3467,8 @@ extension SimpleTypeSpecifierSyntax { return .keyword(.transferring) case ._resultDependsOn: return .keyword(._resultDependsOn) + case .sending: + return .keyword(.sending) } } } diff --git a/Sources/SwiftSyntax/generated/Keyword.swift b/Sources/SwiftSyntax/generated/Keyword.swift index cac53c2e012..e0bde33ba27 100644 --- a/Sources/SwiftSyntax/generated/Keyword.swift +++ b/Sources/SwiftSyntax/generated/Keyword.swift @@ -211,6 +211,10 @@ public enum Keyword: UInt8, Hashable, Sendable { #endif case scoped case `self` + #if compiler(>=5.8) + @_spi(ExperimentalLanguageFeatures) + #endif + case sending case `Self` case Sendable case set @@ -492,6 +496,8 @@ public enum Keyword: UInt8, Hashable, Sendable { self = .renamed case "reverse": self = .reverse + case "sending": + self = .sending case "unowned": self = .unowned case "willSet": @@ -1002,6 +1008,7 @@ public enum Keyword: UInt8, Hashable, Sendable { "safe", "scoped", "self", + "sending", "Self", "Sendable", "set", diff --git a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift index 78a19373b2d..a89af563bba 100644 --- a/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift +++ b/Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift @@ -799,7 +799,8 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { .keyword("static"), .keyword("transferring"), .keyword("unowned"), - .keyword("weak") + .keyword("weak"), + .keyword("sending") ])) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) assertNoError(kind, 3, verify(layout[3], as: RawDeclModifierDetailSyntax?.self)) @@ -2298,7 +2299,8 @@ func validateLayout(layout: RawSyntaxBuffer, as kind: SyntaxKind) { .keyword("borrowing"), .keyword("consuming"), .keyword("transferring"), - .keyword("_resultDependsOn") + .keyword("_resultDependsOn"), + .keyword("sending") ])) assertNoError(kind, 2, verify(layout[2], as: RawUnexpectedNodesSyntax?.self)) case .someOrAnyType: diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesD.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesD.swift index 09173a3c496..1a407a0fdb1 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesD.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesD.swift @@ -169,7 +169,7 @@ public struct DeclModifierDetailSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyn /// ### Children /// -/// - `name`: (`__consuming` | `__setter_access` | `_const` | `_local` | `actor` | `async` | `borrowing` | `class` | `consuming` | `convenience` | `distributed` | `dynamic` | `fileprivate` | `final` | `indirect` | `infix` | `internal` | `isolated` | `lazy` | `mutating` | `nonisolated` | `nonmutating` | `open` | `optional` | `override` | `package` | `postfix` | `prefix` | `private` | `public` | `reasync` | `_resultDependsOnSelf` | `required` | `static` | `transferring` | `unowned` | `weak`) +/// - `name`: (`__consuming` | `__setter_access` | `_const` | `_local` | `actor` | `async` | `borrowing` | `class` | `consuming` | `convenience` | `distributed` | `dynamic` | `fileprivate` | `final` | `indirect` | `infix` | `internal` | `isolated` | `lazy` | `mutating` | `nonisolated` | `nonmutating` | `open` | `optional` | `override` | `package` | `postfix` | `prefix` | `private` | `public` | `reasync` | `_resultDependsOnSelf` | `required` | `static` | `transferring` | `unowned` | `weak` | `sending`) /// - `detail`: ``DeclModifierDetailSyntax``? /// /// ### Contained in @@ -276,6 +276,7 @@ public struct DeclModifierSyntax: SyntaxProtocol, SyntaxHashable, _LeafSyntaxNod /// - `transferring` /// - `unowned` /// - `weak` + /// - `sending` public var name: TokenSyntax { get { return Syntax(self).child(at: 1)!.cast(TokenSyntax.self) diff --git a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift index c58d6442104..1a9479daec9 100644 --- a/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift +++ b/Sources/SwiftSyntax/generated/syntaxNodes/SyntaxNodesQRS.swift @@ -1090,7 +1090,7 @@ public struct SimpleStringLiteralExprSyntax: ExprSyntaxProtocol, SyntaxHashable, /// /// ### Children /// -/// - `specifier`: (`inout` | `__shared` | `__owned` | `isolated` | `_const` | `borrowing` | `consuming` | `transferring` | `_resultDependsOn`) +/// - `specifier`: (`inout` | `__shared` | `__owned` | `isolated` | `_const` | `borrowing` | `consuming` | `transferring` | `_resultDependsOn` | `sending`) /// /// ### Contained in /// @@ -1156,6 +1156,7 @@ public struct SimpleTypeSpecifierSyntax: SyntaxProtocol, SyntaxHashable, _LeafSy /// - `consuming` /// - `transferring` /// - `_resultDependsOn` + /// - `sending` public var specifier: TokenSyntax { get { return Syntax(self).child(at: 1)!.cast(TokenSyntax.self) diff --git a/Tests/SwiftParserTest/DeclarationTests.swift b/Tests/SwiftParserTest/DeclarationTests.swift index 19759906dcd..f1c71339d82 100644 --- a/Tests/SwiftParserTest/DeclarationTests.swift +++ b/Tests/SwiftParserTest/DeclarationTests.swift @@ -3308,4 +3308,19 @@ final class DeclarationTests: ParserTestCase { experimentalFeatures: .transferringArgsAndResults ) } + + func testSendingTypeSpecifier() { + assertParse( + "func testVarDeclTupleElt() -> (sending String, String) {}", + experimentalFeatures: .sendingArgsAndResults + ) + assertParse( + "func testVarDeclTuple2(_ x: (sending String)) {}", + experimentalFeatures: .sendingArgsAndResults + ) + assertParse( + "func testVarDeclTuple2(_ x: (sending String, String)) {}", + experimentalFeatures: .sendingArgsAndResults + ) + } }