Skip to content

Commit a7f65cd

Browse files
committed
[SwiftParser] Allow nonisolated modifier to have a single nonsending argument
This is part of SE-0461 proposal where `nonisolated` has to be marked as `nonsending` in type context to indicate that the function type it's attached to is caller isolated.
1 parent 35a9cde commit a7f65cd

23 files changed

+759
-18
lines changed

CodeGeneration/Sources/SyntaxSupport/SyntaxNodeKind.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ public enum SyntaxNodeKind: String, CaseIterable, IdentifierConvertible, TypeCon
210210
case multipleTrailingClosureElementList
211211
case namedOpaqueReturnType
212212
case nilLiteralExpr
213+
case nonisolatedSpecifierArgument
214+
case nonisolatedSpecifierArgumentList
215+
case nonisolatedTypeSpecifier
213216
case objCSelectorPiece
214217
case objCSelectorPieceList
215218
case operatorDecl

CodeGeneration/Sources/SyntaxSupport/TypeNodes.swift

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,52 @@ public let TYPE_NODES: [Node] = [
676676
]
677677
),
678678

679+
Node(
680+
kind: .nonisolatedSpecifierArgument,
681+
base: .syntax,
682+
nameForDiagnostics: nil,
683+
documentation: """
684+
A single argument that can be added to a nonisolated specifier: 'nonsending'.
685+
686+
### Example
687+
`data` in `func foo(data: nonisolated(nonsending) () async -> Void) -> X`
688+
""",
689+
traits: [
690+
"Parenthesized"
691+
],
692+
children: [
693+
Child(
694+
name: "leftParen",
695+
kind: .token(choices: [.token(.leftParen)])
696+
),
697+
Child(
698+
name: "nonsendingKeyword",
699+
kind: .token(choices: [.keyword(.nonsending)])
700+
),
701+
Child(
702+
name: "rightParen",
703+
kind: .token(choices: [.token(.rightParen)])
704+
),
705+
]
706+
),
707+
708+
Node(
709+
kind: .nonisolatedTypeSpecifier,
710+
base: .syntax,
711+
nameForDiagnostics: "'nonisolated' specifier",
712+
children: [
713+
Child(
714+
name: "nonisolatedKeyword",
715+
kind: .token(choices: [.keyword(.nonisolated)])
716+
),
717+
Child(
718+
name: "argument",
719+
kind: .node(kind: .nonisolatedSpecifierArgument),
720+
isOptional: true
721+
),
722+
]
723+
),
724+
679725
Node(
680726
kind: .simpleTypeSpecifier,
681727
base: .syntax,
@@ -689,7 +735,6 @@ public let TYPE_NODES: [Node] = [
689735
.keyword(.__shared),
690736
.keyword(.__owned),
691737
.keyword(.isolated),
692-
.keyword(.nonisolated),
693738
.keyword(._const),
694739
.keyword(.borrowing),
695740
.keyword(.consuming),
@@ -704,6 +749,6 @@ public let TYPE_NODES: [Node] = [
704749
kind: .typeSpecifierList,
705750
base: .syntaxCollection,
706751
nameForDiagnostics: nil,
707-
elementChoices: [.simpleTypeSpecifier, .lifetimeTypeSpecifier]
752+
elementChoices: [.simpleTypeSpecifier, .lifetimeTypeSpecifier, .nonisolatedTypeSpecifier]
708753
),
709754
]

Sources/SwiftParser/Types.swift

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,40 @@ extension Parser {
10561056
return .lifetimeTypeSpecifier(lifetimeSpecifier)
10571057
}
10581058

1059+
private mutating func parseNonisolatedTypeSpecifier() -> RawTypeSpecifierListSyntax.Element {
1060+
let (unexpectedBeforeNonisolatedKeyword, nonisolatedKeyword) = self.expect(.keyword(.nonisolated))
1061+
1062+
guard let leftParen = self.consume(if: .leftParen) else {
1063+
let nonisolatedSpecifier = RawNonisolatedTypeSpecifierSyntax(
1064+
unexpectedBeforeNonisolatedKeyword,
1065+
nonisolatedKeyword: nonisolatedKeyword,
1066+
argument: nil,
1067+
arena: self.arena
1068+
)
1069+
return .nonisolatedTypeSpecifier(nonisolatedSpecifier)
1070+
}
1071+
1072+
let (unexpectedBeforeModifier, modifier) = self.expect(.keyword(.nonsending))
1073+
let (unexpectedBeforeRightParen, rightParen) = self.expect(.rightParen)
1074+
1075+
let argument = RawNonisolatedSpecifierArgumentSyntax(
1076+
leftParen: leftParen,
1077+
unexpectedBeforeModifier,
1078+
nonsendingKeyword: modifier,
1079+
unexpectedBeforeRightParen,
1080+
rightParen: rightParen,
1081+
arena: self.arena
1082+
)
1083+
1084+
let nonisolatedSpecifier = RawNonisolatedTypeSpecifierSyntax(
1085+
unexpectedBeforeNonisolatedKeyword,
1086+
nonisolatedKeyword: nonisolatedKeyword,
1087+
argument: argument,
1088+
arena: self.arena
1089+
)
1090+
return .nonisolatedTypeSpecifier(nonisolatedSpecifier)
1091+
}
1092+
10591093
private mutating func parseSimpleTypeSpecifier(
10601094
specifierHandle: TokenConsumptionHandle
10611095
) -> RawTypeSpecifierListSyntax.Element {
@@ -1079,6 +1113,8 @@ extension Parser {
10791113
} else {
10801114
break SPECIFIER_PARSING
10811115
}
1116+
} else if self.at(.keyword(.nonisolated)) {
1117+
specifiers.append(parseNonisolatedTypeSpecifier())
10821118
} else {
10831119
break SPECIFIER_PARSING
10841120
}

Sources/SwiftParser/generated/Parser+TokenSpecSet.swift

Lines changed: 0 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/SwiftParserDiagnostics/SyntaxExtensions.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ extension TypeSpecifierListSyntax {
212212
switch specifier {
213213
case .simpleTypeSpecifier(let specifier): return specifier.specifier
214214
case .lifetimeTypeSpecifier: return nil
215+
case .nonisolatedTypeSpecifier: return nil
215216
#if RESILIENT_LIBRARIES
216217
@unknown default:
217218
fatalError()

Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/SwiftSyntax/Documentation.docc/generated/SwiftSyntax.md

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/SwiftSyntax/generated/SyntaxCollections.swift

Lines changed: 33 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/SwiftSyntax/generated/SyntaxEnum.swift

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Sources/SwiftSyntax/generated/SyntaxKind.swift

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)