Skip to content

Commit f78d872

Browse files
committed
Reduce usage of RawSyntax.arena
1 parent acb7943 commit f78d872

File tree

6 files changed

+47
-29
lines changed

6 files changed

+47
-29
lines changed

CodeGeneration/Sources/generate-swift-syntax/templates/swiftparser/LayoutNodesParsableFile.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ let layoutNodesParsableFile = SourceFileSyntax(leadingTrivia: copyrightHeader) {
4141
defer { withExtendedLifetime(parser) {} }
4242
let node = parser.\(parserFunction)()
4343
let raw = RawSyntax(parser.parseRemainder(into: node))
44-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
44+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
4545
}
4646
}
4747
"""

Sources/SwiftParser/generated/LayoutNodes+Parsable.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extension AccessorBlockSyntax: SyntaxParseable {
3232
}
3333
let node = parser.parseAccessorBlock()
3434
let raw = RawSyntax(parser.parseRemainder(into: node))
35-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
35+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
3636
}
3737
}
3838

@@ -50,7 +50,7 @@ extension AccessorDeclSyntax: SyntaxParseable {
5050
}
5151
let node = parser.parseAccessorDecl()
5252
let raw = RawSyntax(parser.parseRemainder(into: node))
53-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
53+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
5454
}
5555
}
5656

@@ -68,7 +68,7 @@ extension AttributeSyntax: SyntaxParseable {
6868
}
6969
let node = parser.parseAttribute()
7070
let raw = RawSyntax(parser.parseRemainder(into: node))
71-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
71+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
7272
}
7373
}
7474

@@ -86,7 +86,7 @@ extension CatchClauseSyntax: SyntaxParseable {
8686
}
8787
let node = parser.parseCatchClause()
8888
let raw = RawSyntax(parser.parseRemainder(into: node))
89-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
89+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
9090
}
9191
}
9292

@@ -104,7 +104,7 @@ extension ClosureParameterSyntax: SyntaxParseable {
104104
}
105105
let node = parser.parseClosureParameter()
106106
let raw = RawSyntax(parser.parseRemainder(into: node))
107-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
107+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
108108
}
109109
}
110110

@@ -122,7 +122,7 @@ extension CodeBlockItemSyntax: SyntaxParseable {
122122
}
123123
let node = parser.parseNonOptionalCodeBlockItem()
124124
let raw = RawSyntax(parser.parseRemainder(into: node))
125-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
125+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
126126
}
127127
}
128128

@@ -140,7 +140,7 @@ extension CodeBlockSyntax: SyntaxParseable {
140140
}
141141
let node = parser.parseCodeBlock()
142142
let raw = RawSyntax(parser.parseRemainder(into: node))
143-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
143+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
144144
}
145145
}
146146

@@ -158,7 +158,7 @@ extension DeclSyntax: SyntaxParseable {
158158
}
159159
let node = parser.parseDeclaration()
160160
let raw = RawSyntax(parser.parseRemainder(into: node))
161-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
161+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
162162
}
163163
}
164164

@@ -176,7 +176,7 @@ extension EnumCaseParameterSyntax: SyntaxParseable {
176176
}
177177
let node = parser.parseEnumCaseParameter()
178178
let raw = RawSyntax(parser.parseRemainder(into: node))
179-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
179+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
180180
}
181181
}
182182

@@ -194,7 +194,7 @@ extension ExprSyntax: SyntaxParseable {
194194
}
195195
let node = parser.parseExpression()
196196
let raw = RawSyntax(parser.parseRemainder(into: node))
197-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
197+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
198198
}
199199
}
200200

@@ -212,7 +212,7 @@ extension FunctionParameterSyntax: SyntaxParseable {
212212
}
213213
let node = parser.parseFunctionParameter()
214214
let raw = RawSyntax(parser.parseRemainder(into: node))
215-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
215+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
216216
}
217217
}
218218

@@ -230,7 +230,7 @@ extension GenericParameterClauseSyntax: SyntaxParseable {
230230
}
231231
let node = parser.parseGenericParameters()
232232
let raw = RawSyntax(parser.parseRemainder(into: node))
233-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
233+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
234234
}
235235
}
236236

@@ -248,7 +248,7 @@ extension MemberBlockSyntax: SyntaxParseable {
248248
}
249249
let node = parser.parseMemberBlock()
250250
let raw = RawSyntax(parser.parseRemainder(into: node))
251-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
251+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
252252
}
253253
}
254254

@@ -266,7 +266,7 @@ extension PatternSyntax: SyntaxParseable {
266266
}
267267
let node = parser.parsePattern()
268268
let raw = RawSyntax(parser.parseRemainder(into: node))
269-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
269+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
270270
}
271271
}
272272

@@ -284,7 +284,7 @@ extension SourceFileSyntax: SyntaxParseable {
284284
}
285285
let node = parser.parseSourceFile()
286286
let raw = RawSyntax(parser.parseRemainder(into: node))
287-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
287+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
288288
}
289289
}
290290

@@ -302,7 +302,7 @@ extension StmtSyntax: SyntaxParseable {
302302
}
303303
let node = parser.parseStatement()
304304
let raw = RawSyntax(parser.parseRemainder(into: node))
305-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
305+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
306306
}
307307
}
308308

@@ -320,7 +320,7 @@ extension SwitchCaseSyntax: SyntaxParseable {
320320
}
321321
let node = parser.parseSwitchCase()
322322
let raw = RawSyntax(parser.parseRemainder(into: node))
323-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
323+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
324324
}
325325
}
326326

@@ -338,7 +338,7 @@ extension TypeSyntax: SyntaxParseable {
338338
}
339339
let node = parser.parseType()
340340
let raw = RawSyntax(parser.parseRemainder(into: node))
341-
return Syntax(raw: raw, rawNodeArena: raw.arena).cast(Self.self)
341+
return Syntax(raw: raw, rawNodeArena: parser.arena).cast(Self.self)
342342
}
343343
}
344344

Sources/SwiftSyntax/Raw/RawSyntax.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ struct RecursiveRawSyntaxFlags: OptionSet, Sendable {
3939
/// Node data for RawSyntax tree. Tagged union plus common data.
4040
internal struct RawSyntaxData: Sendable {
4141
internal enum Payload: Sendable {
42+
/// - Important: A raw syntax node for a parsed token must always be allocated in a `ParsingSyntaxArena` so we can
43+
/// parse the trivia in the token.
4244
case parsedToken(ParsedToken)
4345
case materializedToken(MaterializedToken)
4446
case layout(Layout)

Sources/SwiftSyntax/Raw/RawSyntaxTokenView.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,7 @@ public struct RawSyntaxTokenView: Sendable {
9595
public var leadingRawTriviaPieces: [RawTriviaPiece] {
9696
switch raw.rawData.payload {
9797
case .parsedToken(let dat):
98-
let arena = raw.arena as! ParsingSyntaxArena
99-
return arena.parseTrivia(source: dat.leadingTriviaText, position: .leading)
98+
return raw.arenaReference.parseTrivia(source: dat.leadingTriviaText, position: .leading)
10099
case .materializedToken(let dat):
101100
return Array(dat.leadingTrivia)
102101
case .layout(_):
@@ -108,8 +107,7 @@ public struct RawSyntaxTokenView: Sendable {
108107
public var trailingRawTriviaPieces: [RawTriviaPiece] {
109108
switch raw.rawData.payload {
110109
case .parsedToken(let dat):
111-
let arena = raw.arena as! ParsingSyntaxArena
112-
return arena.parseTrivia(source: dat.trailingTriviaText, position: .trailing)
110+
return raw.arenaReference.parseTrivia(source: dat.trailingTriviaText, position: .trailing)
113111
case .materializedToken(let dat):
114112
return Array(dat.trailingTrivia)
115113
case .layout(_):
@@ -204,7 +202,7 @@ public struct RawSyntaxTokenView: Sendable {
204202
arena.addChild(self.raw.arenaReference)
205203
switch raw.rawData.payload {
206204
case .parsedToken(var payload):
207-
if arena === self.raw.arena {
205+
if arena == self.raw.arenaReference {
208206
payload.presence = newValue
209207
return RawSyntax(arena: arena, payload: .parsedToken(payload))
210208
}
@@ -287,7 +285,7 @@ public struct RawSyntaxTokenView: Sendable {
287285
arena.addChild(self.raw.arenaReference)
288286
switch raw.rawData.payload {
289287
case .parsedToken(var dat):
290-
if arena === self.raw.arena {
288+
if arena == self.raw.arenaReference {
291289
dat.tokenDiagnostic = tokenDiagnostic
292290
return RawSyntax(arena: arena, payload: .parsedToken(dat))
293291
}

Sources/SwiftSyntax/Syntax.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable {
126126
/// make sure the arena doesn’t get de-allocated before the ``Syntax``
127127
/// has a chance to retain it.
128128
static func forRoot(_ raw: RawSyntax, rawNodeArena: SyntaxArena) -> Syntax {
129-
precondition(rawNodeArena === raw.arena)
129+
precondition(rawNodeArena == raw.arenaReference)
130130
return Syntax(raw, info: .root(.init(arena: rawNodeArena)))
131131
}
132132

@@ -158,7 +158,7 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable {
158158
/// - Returns: A syntax tree with all parents where this node has been
159159
/// replaced by `newRaw`
160160
func replacingSelf(_ newRaw: RawSyntax, rawNodeArena: SyntaxArena, allocationArena: SyntaxArena) -> Syntax {
161-
precondition(newRaw.arena === rawNodeArena)
161+
precondition(newRaw.arenaReference == rawNodeArena)
162162
// If we have a parent already, then ask our current parent to copy itself
163163
// recursively up to the root.
164164
if let parent {
@@ -183,7 +183,7 @@ public struct Syntax: SyntaxProtocol, SyntaxHashable {
183183
/// syntax data.
184184
/// - SeeAlso: replacingSelf(_:)
185185
func replacingChild(at index: Int, with newChild: RawSyntax?, rawNodeArena: SyntaxArena?, allocationArena: SyntaxArena) -> Syntax {
186-
precondition(newChild?.arena === rawNodeArena || newChild == nil)
186+
precondition(newChild == nil || (rawNodeArena != nil && newChild!.arenaReference == rawNodeArena!))
187187
// After newRaw has been allocated in `allocationArena`, `rawNodeArena` will
188188
// be a child arena of `allocationArena` and thus, `allocationArena` will
189189
// keep `newChild` alive.

Sources/SwiftSyntax/SyntaxArena.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,9 @@ public class ParsingSyntaxArena: SyntaxArena {
178178
private var sourceBuffer: UnsafeBufferPointer<UInt8>
179179

180180
/// Function to parse trivia.
181-
private var parseTriviaFunction: ParseTriviaFunction
181+
///
182+
/// - Important: Must never be changed to a mutable value. See `SyntaxArenaRef.parseTrivia`.
183+
private let parseTriviaFunction: ParseTriviaFunction
182184

183185
@_spi(RawSyntax)
184186
public init(parseTriviaFunction: @escaping ParseTriviaFunction) {
@@ -227,6 +229,7 @@ public class ParsingSyntaxArena: SyntaxArena {
227229
/// Parse `source` into a list of ``RawTriviaPiece`` using `parseTriviaFunction`.
228230
@_spi(RawSyntax)
229231
public func parseTrivia(source: SyntaxText, position: TriviaPosition) -> [RawTriviaPiece] {
232+
// Must never access mutable state. See `SyntaxArenaRef.parseTrivia`.
230233
return self.parseTriviaFunction(source, position)
231234
}
232235
}
@@ -249,6 +252,13 @@ struct SyntaxArenaRef: Hashable, @unchecked Sendable {
249252
get { self._value.takeUnretainedValue() }
250253
}
251254

255+
/// Assuming that this references a `ParsingSyntaxArena`,
256+
func parseTrivia(source: SyntaxText, position: TriviaPosition) -> [RawTriviaPiece] {
257+
// It is safe to access `_value` here because `parseTrivia` only accesses
258+
// `parseTriviaFunction`, which is a constant.
259+
(_value.takeUnretainedValue() as! ParsingSyntaxArena).parseTrivia(source: source, position: position)
260+
}
261+
252262
func retain() {
253263
_ = self._value.retain()
254264
}
@@ -264,4 +274,12 @@ struct SyntaxArenaRef: Hashable, @unchecked Sendable {
264274
static func == (lhs: SyntaxArenaRef, rhs: SyntaxArenaRef) -> Bool {
265275
return lhs._value.toOpaque() == rhs._value.toOpaque()
266276
}
277+
278+
static func == (lhs: SyntaxArenaRef, rhs: __shared SyntaxArena) -> Bool {
279+
return lhs == SyntaxArenaRef(rhs)
280+
}
281+
282+
static func == (lhs: __shared SyntaxArena, rhs: SyntaxArenaRef) -> Bool {
283+
return rhs == lhs
284+
}
267285
}

0 commit comments

Comments
 (0)