Skip to content

Commit fcc4880

Browse files
authored
Merge pull request #1644 from kavon/forget-to-discard
support parsing `discard` in place of `_forget`
2 parents 8311d8d + 2c97ee0 commit fcc4880

19 files changed

+358
-325
lines changed

CodeGeneration/Sources/SyntaxSupport/KeywordSpec.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ public let KEYWORDS: [KeywordSpec] = [
138138
KeywordSpec("fileprivate", isLexerClassified: true, requiresTrailingSpace: true),
139139
KeywordSpec("final"),
140140
KeywordSpec("for", isLexerClassified: true, requiresTrailingSpace: true),
141-
KeywordSpec("_forget"),
141+
KeywordSpec("_forget"), // NOTE: support for deprecated _forget
142+
KeywordSpec("discard"),
142143
KeywordSpec("forward"),
143144
KeywordSpec("func", isLexerClassified: true, requiresTrailingSpace: true),
144145
KeywordSpec("get"),

CodeGeneration/Sources/SyntaxSupport/StmtNodes.swift

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -333,15 +333,18 @@ public let STMT_NODES: [Node] = [
333333
]
334334
),
335335

336-
// forget-stmt -> 'forget' expr ';'?
336+
// discard-stmt -> 'discard' expr ';'?
337337
Node(
338-
name: "ForgetStmt",
339-
nameForDiagnostics: "'forget' statement",
338+
name: "DiscardStmt",
339+
nameForDiagnostics: "'discard' statement",
340340
kind: "Stmt",
341341
children: [
342342
Child(
343-
name: "ForgetKeyword",
344-
kind: .token(choices: [.keyword(text: "_forget")])
343+
name: "DiscardKeyword",
344+
kind: .token(choices: [
345+
.keyword(text: "_forget"), // NOTE: support for deprecated _forget
346+
.keyword(text: "discard"),
347+
])
345348
),
346349
Child(
347350
name: "Expression",

Sources/SwiftParser/Statements.swift

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ extension Parser {
5555
/// statement → control-transfer-statement ';'?
5656
/// statement → defer-statement ';'?
5757
/// statement → do-statement ';'?
58-
/// statement → forget-statement ';'?
58+
/// statement → discard-statement ';'?
5959
///
6060
/// loop-statement → for-in-statement
6161
/// loop-statement → while-statement
@@ -124,8 +124,10 @@ extension Parser {
124124
return label(self.parseContinueStatement(continueHandle: handle), with: optLabel)
125125
case (.fallthroughKeyword, let handle)?:
126126
return label(self.parseFallthroughStatement(fallthroughHandle: handle), with: optLabel)
127-
case (.forgetKeyword, let handle)?:
128-
return label(self.parseForgetStatement(forgetHandle: handle), with: optLabel)
127+
case (.forgetKeyword, let handle)?: // NOTE: support for deprecated _forget
128+
fallthrough
129+
case (.discardKeyword, let handle)?:
130+
return label(self.parseDiscardStatement(discardHandle: handle), with: optLabel)
129131
case (.returnKeyword, let handle)?:
130132
return label(self.parseReturnStatement(returnHandle: handle), with: optLabel)
131133
case (.throwKeyword, let handle)?:
@@ -393,22 +395,24 @@ extension Parser {
393395
}
394396
}
395397

396-
// MARK: Forget Statements
398+
// MARK: Discard Statements
397399

398400
extension Parser {
399-
/// Parse a forget statement.
401+
/// Parse a discard statement.
400402
///
401403
/// Grammar
402404
/// =======
403405
///
404-
/// forget-statement → 'forget' expression
406+
/// discard-statement → 'discard' expression
407+
///
408+
/// where expression's first token is an identifier.
405409
@_spi(RawSyntax)
406-
public mutating func parseForgetStatement(forgetHandle: RecoveryConsumptionHandle) -> RawForgetStmtSyntax {
407-
let (unexpectedBeforeForgetKeyword, forgetKeyword) = self.eat(forgetHandle)
410+
public mutating func parseDiscardStatement(discardHandle: RecoveryConsumptionHandle) -> RawDiscardStmtSyntax {
411+
let (unexpectedBeforeDiscardKeyword, discardKeyword) = self.eat(discardHandle)
408412
let expr = self.parseExpression()
409-
return RawForgetStmtSyntax(
410-
unexpectedBeforeForgetKeyword,
411-
forgetKeyword: forgetKeyword,
413+
return RawDiscardStmtSyntax(
414+
unexpectedBeforeDiscardKeyword,
415+
discardKeyword: discardKeyword,
412416
expression: expr,
413417
arena: self.arena
414418
)
@@ -1009,22 +1013,24 @@ extension Parser.Lookahead {
10091013
// yield statement of some singular expression.
10101014
return !self.peek().isAtStartOfLine
10111015
}
1012-
case .forgetKeyword?:
1016+
case .forgetKeyword?: // NOTE: support for deprecated _forget
1017+
fallthrough
1018+
case .discardKeyword?:
10131019
let next = peek()
1014-
// The thing to be forgotten must be on the same line as `forget`.
1020+
// The thing to be discarded must be on the same line as `discard`.
10151021
if next.isAtStartOfLine {
10161022
return false
10171023
}
10181024
switch next.rawTokenKind {
10191025
case .identifier, .keyword:
10201026
// Since some identifiers like "self" are classified as keywords,
1021-
// we want to recognize those too, to handle "forget self". We also
1027+
// we want to recognize those too, to handle "discard self". We also
10221028
// accept any identifier since we want to emit a nice error message
10231029
// later on during type checking.
10241030
return true
10251031
default:
1026-
// any other token following "forget" means it's not the statement.
1027-
// For example, could be the function call "forget()".
1032+
// any other token following "discard" means it's not the statement.
1033+
// For example, could be the function call "discard()".
10281034
return false
10291035
}
10301036
case nil:

Sources/SwiftParser/TokenSpecSet.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ enum CanBeStatementStart: TokenSpecSet {
8080
case doKeyword
8181
case fallthroughKeyword
8282
case forKeyword
83-
case forgetKeyword
83+
case forgetKeyword // NOTE: support for deprecated _forget
84+
case discardKeyword
8485
case guardKeyword
8586
case ifKeyword
8687
case repeatKeyword
@@ -99,6 +100,7 @@ enum CanBeStatementStart: TokenSpecSet {
99100
case TokenSpec(.fallthrough): self = .fallthroughKeyword
100101
case TokenSpec(.for): self = .forKeyword
101102
case TokenSpec(._forget): self = .forgetKeyword
103+
case TokenSpec(.discard): self = .discardKeyword
102104
case TokenSpec(.guard): self = .guardKeyword
103105
case TokenSpec(.if): self = .ifKeyword
104106
case TokenSpec(.repeat): self = .repeatKeyword
@@ -120,6 +122,7 @@ enum CanBeStatementStart: TokenSpecSet {
120122
case .fallthroughKeyword: return .keyword(.fallthrough)
121123
case .forKeyword: return .keyword(.for)
122124
case .forgetKeyword: return TokenSpec(._forget, recoveryPrecedence: .stmtKeyword)
125+
case .discardKeyword: return TokenSpec(.discard, recoveryPrecedence: .stmtKeyword)
123126
case .guardKeyword: return .keyword(.guard)
124127
case .ifKeyword: return .keyword(.if)
125128
case .repeatKeyword: return .keyword(.repeat)

Sources/SwiftParserDiagnostics/generated/SyntaxKindNameForDiagnostics.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ extension SyntaxKind {
135135
return "differentiability parameters"
136136
case .differentiableAttributeArguments:
137137
return "'@differentiable' arguments"
138+
case .discardStmt:
139+
return "'discard' statement"
138140
case .doStmt:
139141
return "'do' statement"
140142
case .documentationAttributeArgument:
@@ -175,8 +177,6 @@ extension SyntaxKind {
175177
return "'for' statement"
176178
case .forcedValueExpr:
177179
return "force unwrap"
178-
case .forgetStmt:
179-
return "'forget' statement"
180180
case .functionCallExpr:
181181
return "function call"
182182
case .functionDecl:

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,11 @@ allows Swift tools to parse, inspect, generate, and transform Swift source code.
155155
- <doc:SwiftSyntax/BreakStmtSyntax>
156156
- <doc:SwiftSyntax/ContinueStmtSyntax>
157157
- <doc:SwiftSyntax/DeferStmtSyntax>
158+
- <doc:SwiftSyntax/DiscardStmtSyntax>
158159
- <doc:SwiftSyntax/DoStmtSyntax>
159160
- <doc:SwiftSyntax/ExpressionStmtSyntax>
160161
- <doc:SwiftSyntax/FallthroughStmtSyntax>
161162
- <doc:SwiftSyntax/ForInStmtSyntax>
162-
- <doc:SwiftSyntax/ForgetStmtSyntax>
163163
- <doc:SwiftSyntax/GuardStmtSyntax>
164164
- <doc:SwiftSyntax/LabeledStmtSyntax>
165165
- <doc:SwiftSyntax/RepeatWhileStmtSyntax>

Sources/SwiftSyntax/generated/ChildNameForKeyPath.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,6 +1033,16 @@ public func childName(_ keyPath: AnyKeyPath) -> String? {
10331033
return "wildcard"
10341034
case \DiscardAssignmentExprSyntax.unexpectedAfterWildcard:
10351035
return "unexpectedAfterWildcard"
1036+
case \DiscardStmtSyntax.unexpectedBeforeDiscardKeyword:
1037+
return "unexpectedBeforeDiscardKeyword"
1038+
case \DiscardStmtSyntax.discardKeyword:
1039+
return "discardKeyword"
1040+
case \DiscardStmtSyntax.unexpectedBetweenDiscardKeywordAndExpression:
1041+
return "unexpectedBetweenDiscardKeywordAndExpression"
1042+
case \DiscardStmtSyntax.expression:
1043+
return "expression"
1044+
case \DiscardStmtSyntax.unexpectedAfterExpression:
1045+
return "unexpectedAfterExpression"
10361046
case \DoStmtSyntax.unexpectedBeforeDoKeyword:
10371047
return "unexpectedBeforeDoKeyword"
10381048
case \DoStmtSyntax.doKeyword:
@@ -1347,16 +1357,6 @@ public func childName(_ keyPath: AnyKeyPath) -> String? {
13471357
return "exclamationMark"
13481358
case \ForcedValueExprSyntax.unexpectedAfterExclamationMark:
13491359
return "unexpectedAfterExclamationMark"
1350-
case \ForgetStmtSyntax.unexpectedBeforeForgetKeyword:
1351-
return "unexpectedBeforeForgetKeyword"
1352-
case \ForgetStmtSyntax.forgetKeyword:
1353-
return "forgetKeyword"
1354-
case \ForgetStmtSyntax.unexpectedBetweenForgetKeywordAndExpression:
1355-
return "unexpectedBetweenForgetKeywordAndExpression"
1356-
case \ForgetStmtSyntax.expression:
1357-
return "expression"
1358-
case \ForgetStmtSyntax.unexpectedAfterExpression:
1359-
return "unexpectedAfterExpression"
13601360
case \FunctionCallExprSyntax.unexpectedBeforeCalledExpression:
13611361
return "unexpectedBeforeCalledExpression"
13621362
case \FunctionCallExprSyntax.calledExpression:

Sources/SwiftSyntax/generated/Keyword.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ public enum Keyword: UInt8, Hashable {
116116
case final
117117
case `for`
118118
case _forget
119+
case discard
119120
case forward
120121
case `func`
121122
case get
@@ -431,6 +432,8 @@ public enum Keyword: UInt8, Hashable {
431432
self = .dynamic
432433
case "_forget":
433434
self = ._forget
435+
case "discard":
436+
self = .discard
434437
case "forward":
435438
self = .forward
436439
case "message":
@@ -853,6 +856,7 @@ public enum Keyword: UInt8, Hashable {
853856
"final",
854857
"for",
855858
"_forget",
859+
"discard",
856860
"forward",
857861
"func",
858862
"get",

Sources/SwiftSyntax/generated/SyntaxAnyVisitor.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,14 @@ open class SyntaxAnyVisitor: SyntaxVisitor {
741741
visitAnyPost(node._syntaxNode)
742742
}
743743

744+
override open func visit(_ node: DiscardStmtSyntax) -> SyntaxVisitorContinueKind {
745+
return visitAny(node._syntaxNode)
746+
}
747+
748+
override open func visitPost(_ node: DiscardStmtSyntax) {
749+
visitAnyPost(node._syntaxNode)
750+
}
751+
744752
override open func visit(_ node: DoStmtSyntax) -> SyntaxVisitorContinueKind {
745753
return visitAny(node._syntaxNode)
746754
}
@@ -933,14 +941,6 @@ open class SyntaxAnyVisitor: SyntaxVisitor {
933941
visitAnyPost(node._syntaxNode)
934942
}
935943

936-
override open func visit(_ node: ForgetStmtSyntax) -> SyntaxVisitorContinueKind {
937-
return visitAny(node._syntaxNode)
938-
}
939-
940-
override open func visitPost(_ node: ForgetStmtSyntax) {
941-
visitAnyPost(node._syntaxNode)
942-
}
943-
944944
override open func visit(_ node: FunctionCallExprSyntax) -> SyntaxVisitorContinueKind {
945945
return visitAny(node._syntaxNode)
946946
}

Sources/SwiftSyntax/generated/SyntaxBaseNodes.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ public struct StmtSyntax: StmtSyntaxProtocol, SyntaxHashable {
485485

486486
public init?<S: SyntaxProtocol>(_ node: S) {
487487
switch node.raw.kind {
488-
case .breakStmt, .continueStmt, .deferStmt, .doStmt, .expressionStmt, .fallthroughStmt, .forInStmt, .forgetStmt, .guardStmt, .labeledStmt, .missingStmt, .repeatWhileStmt, .returnStmt, .throwStmt, .whileStmt, .yieldStmt:
488+
case .breakStmt, .continueStmt, .deferStmt, .discardStmt, .doStmt, .expressionStmt, .fallthroughStmt, .forInStmt, .guardStmt, .labeledStmt, .missingStmt, .repeatWhileStmt, .returnStmt, .throwStmt, .whileStmt, .yieldStmt:
489489
self._syntaxNode = node._syntaxNode
490490
default:
491491
return nil
@@ -497,7 +497,7 @@ public struct StmtSyntax: StmtSyntaxProtocol, SyntaxHashable {
497497
/// is undefined.
498498
internal init(_ data: SyntaxData) {
499499
switch data.raw.kind {
500-
case .breakStmt, .continueStmt, .deferStmt, .doStmt, .expressionStmt, .fallthroughStmt, .forInStmt, .forgetStmt, .guardStmt, .labeledStmt, .missingStmt, .repeatWhileStmt, .returnStmt, .throwStmt, .whileStmt, .yieldStmt:
500+
case .breakStmt, .continueStmt, .deferStmt, .discardStmt, .doStmt, .expressionStmt, .fallthroughStmt, .forInStmt, .guardStmt, .labeledStmt, .missingStmt, .repeatWhileStmt, .returnStmt, .throwStmt, .whileStmt, .yieldStmt:
501501
break
502502
default:
503503
preconditionFailure("Unable to create StmtSyntax from \(data.raw.kind)")
@@ -536,11 +536,11 @@ public struct StmtSyntax: StmtSyntaxProtocol, SyntaxHashable {
536536
.node(BreakStmtSyntax.self),
537537
.node(ContinueStmtSyntax.self),
538538
.node(DeferStmtSyntax.self),
539+
.node(DiscardStmtSyntax.self),
539540
.node(DoStmtSyntax.self),
540541
.node(ExpressionStmtSyntax.self),
541542
.node(FallthroughStmtSyntax.self),
542543
.node(ForInStmtSyntax.self),
543-
.node(ForgetStmtSyntax.self),
544544
.node(GuardStmtSyntax.self),
545545
.node(LabeledStmtSyntax.self),
546546
.node(MissingStmtSyntax.self),
@@ -772,6 +772,7 @@ extension Syntax {
772772
.node(DifferentiabilityParamsSyntax.self),
773773
.node(DifferentiableAttributeArgumentsSyntax.self),
774774
.node(DiscardAssignmentExprSyntax.self),
775+
.node(DiscardStmtSyntax.self),
775776
.node(DoStmtSyntax.self),
776777
.node(DocumentationAttributeArgumentSyntax.self),
777778
.node(DocumentationAttributeArgumentsSyntax.self),
@@ -796,7 +797,6 @@ extension Syntax {
796797
.node(FloatLiteralExprSyntax.self),
797798
.node(ForInStmtSyntax.self),
798799
.node(ForcedValueExprSyntax.self),
799-
.node(ForgetStmtSyntax.self),
800800
.node(FunctionCallExprSyntax.self),
801801
.node(FunctionDeclSyntax.self),
802802
.node(FunctionEffectSpecifiersSyntax.self),

Sources/SwiftSyntax/generated/SyntaxEnum.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ public enum SyntaxEnum {
102102
case differentiabilityParams(DifferentiabilityParamsSyntax)
103103
case differentiableAttributeArguments(DifferentiableAttributeArgumentsSyntax)
104104
case discardAssignmentExpr(DiscardAssignmentExprSyntax)
105+
case discardStmt(DiscardStmtSyntax)
105106
case doStmt(DoStmtSyntax)
106107
case documentationAttributeArgument(DocumentationAttributeArgumentSyntax)
107108
case documentationAttributeArguments(DocumentationAttributeArgumentsSyntax)
@@ -126,7 +127,6 @@ public enum SyntaxEnum {
126127
case floatLiteralExpr(FloatLiteralExprSyntax)
127128
case forInStmt(ForInStmtSyntax)
128129
case forcedValueExpr(ForcedValueExprSyntax)
129-
case forgetStmt(ForgetStmtSyntax)
130130
case functionCallExpr(FunctionCallExprSyntax)
131131
case functionDecl(FunctionDeclSyntax)
132132
case functionEffectSpecifiers(FunctionEffectSpecifiersSyntax)
@@ -469,6 +469,8 @@ public extension Syntax {
469469
return .differentiableAttributeArguments(DifferentiableAttributeArgumentsSyntax(self)!)
470470
case .discardAssignmentExpr:
471471
return .discardAssignmentExpr(DiscardAssignmentExprSyntax(self)!)
472+
case .discardStmt:
473+
return .discardStmt(DiscardStmtSyntax(self)!)
472474
case .doStmt:
473475
return .doStmt(DoStmtSyntax(self)!)
474476
case .documentationAttributeArgument:
@@ -517,8 +519,6 @@ public extension Syntax {
517519
return .forInStmt(ForInStmtSyntax(self)!)
518520
case .forcedValueExpr:
519521
return .forcedValueExpr(ForcedValueExprSyntax(self)!)
520-
case .forgetStmt:
521-
return .forgetStmt(ForgetStmtSyntax(self)!)
522522
case .functionCallExpr:
523523
return .functionCallExpr(FunctionCallExprSyntax(self)!)
524524
case .functionDecl:

Sources/SwiftSyntax/generated/SyntaxKind.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ public enum SyntaxKind {
102102
case differentiabilityParams
103103
case differentiableAttributeArguments
104104
case discardAssignmentExpr
105+
case discardStmt
105106
case doStmt
106107
case documentationAttributeArgument
107108
case documentationAttributeArguments
@@ -126,7 +127,6 @@ public enum SyntaxKind {
126127
case floatLiteralExpr
127128
case forInStmt
128129
case forcedValueExpr
129-
case forgetStmt
130130
case functionCallExpr
131131
case functionDecl
132132
case functionEffectSpecifiers
@@ -586,6 +586,8 @@ public enum SyntaxKind {
586586
return DifferentiableAttributeArgumentsSyntax.self
587587
case .discardAssignmentExpr:
588588
return DiscardAssignmentExprSyntax.self
589+
case .discardStmt:
590+
return DiscardStmtSyntax.self
589591
case .doStmt:
590592
return DoStmtSyntax.self
591593
case .documentationAttributeArgument:
@@ -634,8 +636,6 @@ public enum SyntaxKind {
634636
return ForInStmtSyntax.self
635637
case .forcedValueExpr:
636638
return ForcedValueExprSyntax.self
637-
case .forgetStmt:
638-
return ForgetStmtSyntax.self
639639
case .functionCallExpr:
640640
return FunctionCallExprSyntax.self
641641
case .functionDecl:

0 commit comments

Comments
 (0)