Skip to content

[sending] Add support for sending #2658

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 18, 2024
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
1 change: 1 addition & 0 deletions CodeGeneration/Sources/SyntaxSupport/DeclNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,7 @@ public let DECL_NODES: [Node] = [
.keyword(.transferring),
.keyword(.unowned),
.keyword(.weak),
.keyword(.sending),
])
),
Child(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public enum ExperimentalFeature: String, CaseIterable {
case nonescapableTypes
case transferringArgsAndResults
case trailingComma
case sendingArgsAndResults

/// The name of the feature, which is used in the doc comment.
public var featureName: String {
Expand All @@ -35,6 +36,8 @@ public enum ExperimentalFeature: String, CaseIterable {
return "TransferringArgsAndResults"
case .trailingComma:
return "trailing comma"
case .sendingArgsAndResults:
return "SendingArgsAndResults"
}
}

Expand Down
6 changes: 6 additions & 0 deletions CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ public enum Keyword: CaseIterable {
case safe
case scoped
case `self`
case sending
case `Self`
case Sendable
case set
Expand Down Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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."
)
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftParser/Declarations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions Sources/SwiftParser/Patterns.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Sources/SwiftParser/TokenPrecedence.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions Sources/SwiftParser/TokenSpecSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,7 @@ enum DeclarationModifier: TokenSpecSet {
case reasync
case required
case `rethrows`
case sending
case `static`
case transferring
case unowned
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions Sources/SwiftParser/generated/ExperimentalFeatures.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,7 @@ extension Parser.ExperimentalFeatures {

/// Whether to enable the parsing of trailing comma.
public static let trailingComma = Self (rawValue: 1 << 5)

/// Whether to enable the parsing of SendingArgsAndResults.
public static let sendingArgsAndResults = Self (rawValue: 1 << 6)
}
24 changes: 24 additions & 0 deletions Sources/SwiftParser/generated/Parser+TokenSpecSet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -972,6 +978,8 @@ extension DeclModifierSyntax {
self = .unowned
case TokenSpec(.weak):
self = .weak
case TokenSpec(.sending):
self = .sending
default:
return nil
}
Expand Down Expand Up @@ -1053,6 +1061,8 @@ extension DeclModifierSyntax {
return .keyword(.unowned)
case .weak:
return .keyword(.weak)
case .sending:
return .keyword(.sending)
}
}

Expand Down Expand Up @@ -1136,6 +1146,8 @@ extension DeclModifierSyntax {
return .keyword(.unowned)
case .weak:
return .keyword(.weak)
case .sending:
return .keyword(.sending)
}
}
}
Expand Down Expand Up @@ -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) {
Expand All @@ -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
}
Expand All @@ -3393,6 +3411,8 @@ extension SimpleTypeSpecifierSyntax {
self = .transferring
case TokenSpec(._resultDependsOn):
self = ._resultDependsOn
case TokenSpec(.sending):
self = .sending
default:
return nil
}
Expand All @@ -3418,6 +3438,8 @@ extension SimpleTypeSpecifierSyntax {
return .keyword(.transferring)
case ._resultDependsOn:
return .keyword(._resultDependsOn)
case .sending:
return .keyword(.sending)
}
}

Expand Down Expand Up @@ -3445,6 +3467,8 @@ extension SimpleTypeSpecifierSyntax {
return .keyword(.transferring)
case ._resultDependsOn:
return .keyword(._resultDependsOn)
case .sending:
return .keyword(.sending)
}
}
}
Expand Down
7 changes: 7 additions & 0 deletions Sources/SwiftSyntax/generated/Keyword.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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":
Expand Down Expand Up @@ -1002,6 +1008,7 @@ public enum Keyword: UInt8, Hashable, Sendable {
"safe",
"scoped",
"self",
"sending",
"Self",
"Sendable",
"set",
Expand Down
6 changes: 4 additions & 2 deletions Sources/SwiftSyntax/generated/raw/RawSyntaxValidation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
///
Expand Down Expand Up @@ -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)
Expand Down
15 changes: 15 additions & 0 deletions Tests/SwiftParserTest/DeclarationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3309,6 +3309,21 @@ final class DeclarationTests: ParserTestCase {
)
}

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
)
}

func testMisplacedAttributeInVarDeclWithMultipleBindings() {
assertParse(
"""
Expand Down