Skip to content

Commit d9fabf7

Browse files
authored
Merge pull request #3020 from rintaro/arena-non-resilient-access
[Syntax] Workaround for 'cannot bypass resilience' warnings
2 parents f015485 + 31182de commit d9fabf7

File tree

2 files changed

+18
-11
lines changed

2 files changed

+18
-11
lines changed

Sources/SwiftSyntax/Raw/RawSyntaxArena.swift

+10-6
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,11 @@ public class RawSyntaxArena {
6363
///
6464
/// - Important: This is only intended to be used for assertions to catch
6565
/// retain cycles in syntax arenas.
66-
fileprivate let hasParent: UnsafeMutablePointer<AtomicBool>
66+
/// - Note: `UnsafeMutableRawPointer` + casting accessor is a workaround to silence the warning 'cannot bypass resilience'.
67+
private let _hasParent: UnsafeMutableRawPointer
68+
fileprivate func hasParent() -> UnsafeMutablePointer<AtomicBool> {
69+
_hasParent.assumingMemoryBound(to: AtomicBool.self)
70+
}
6771
#endif
6872

6973
/// Construct a new ``RawSyntaxArena`` in which syntax nodes can be allocated.
@@ -75,7 +79,7 @@ public class RawSyntaxArena {
7579
self.allocator = BumpPtrAllocator(initialSlabSize: slabSize)
7680
self.childRefs = []
7781
#if DEBUG || SWIFTSYNTAX_ENABLE_ASSERTIONS
78-
self.hasParent = swiftsyntax_atomic_bool_create(false)
82+
self._hasParent = UnsafeMutableRawPointer(swiftsyntax_atomic_bool_create(false))
7983
#endif
8084
}
8185

@@ -84,7 +88,7 @@ public class RawSyntaxArena {
8488
child.release()
8589
}
8690
#if DEBUG || SWIFTSYNTAX_ENABLE_ASSERTIONS
87-
swiftsyntax_atomic_bool_destroy(self.hasParent)
91+
swiftsyntax_atomic_bool_destroy(self.hasParent())
8892
#endif
8993
}
9094

@@ -153,7 +157,7 @@ public class RawSyntaxArena {
153157

154158
#if DEBUG || SWIFTSYNTAX_ENABLE_ASSERTIONS
155159
precondition(
156-
!swiftsyntax_atomic_bool_get(self.hasParent),
160+
!swiftsyntax_atomic_bool_get(self.hasParent()),
157161
"an arena can't have a new child once it's owned by other arenas"
158162
)
159163
#endif
@@ -299,12 +303,12 @@ struct RawSyntaxArenaRef: Hashable, @unchecked Sendable {
299303
#if DEBUG || SWIFTSYNTAX_ENABLE_ASSERTIONS
300304
/// Accessor for the underlying's `RawSyntaxArena.hasParent`
301305
var hasParent: Bool {
302-
swiftsyntax_atomic_bool_get(value.hasParent)
306+
swiftsyntax_atomic_bool_get(value.hasParent())
303307
}
304308

305309
/// Sets the `RawSyntaxArena.hasParent` on the referenced arena.
306310
func setHasParent(_ newValue: Bool) {
307-
swiftsyntax_atomic_bool_set(value.hasParent, newValue)
311+
swiftsyntax_atomic_bool_set(value.hasParent(), newValue)
308312
}
309313
#endif
310314

Sources/SwiftSyntax/Syntax.swift

+8-5
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,10 @@ struct SyntaxData: Sendable {
382382
/// `SyntaxDataArena` manages the entire data of a `Syntax` tree.
383383
final class SyntaxDataArena: @unchecked Sendable {
384384
/// Mutex for locking the data when populating layout buffers.
385-
private let mutex: PlatformMutex
385+
///
386+
/// - Note: `UnsafeMutableRawPointer` + casting accessor is a workaround to silence the warning 'cannot bypass resilience'.
387+
private let _mutex: UnsafeMutableRawPointer?
388+
private func mutex() -> PlatformMutex { PlatformMutex(opaque: self._mutex) }
386389

387390
/// Allocator.
388391
private let allocator: BumpPtrAllocator
@@ -396,7 +399,7 @@ final class SyntaxDataArena: @unchecked Sendable {
396399
init(raw: RawSyntax, rawNodeArena: RetainedRawSyntaxArena) {
397400
precondition(rawNodeArena == raw.arenaReference)
398401

399-
self.mutex = PlatformMutex.create()
402+
self._mutex = PlatformMutex.create().opaque
400403
self.allocator = BumpPtrAllocator(initialSlabSize: Self.slabSize(for: raw))
401404
self.rawArena = rawNodeArena
402405
self.root = Self.createDataImpl(allocator: allocator, raw: raw, parent: nil, absoluteInfo: .forRoot(raw))
@@ -405,7 +408,7 @@ final class SyntaxDataArena: @unchecked Sendable {
405408
deinit {
406409
// Debug print for re-evaluating `slabSize(for:)`
407410
// print("nodeCount: \(root.pointee.raw.totalNodes), slabSize: \(Self.slabSize(for: root.pointee.raw)), allocated: \(allocator.totalByteSizeAllocated), overflowed: \(Self.slabSize(for: root.pointee.raw) < allocator.totalByteSizeAllocated)")
408-
self.mutex.destroy()
411+
self.mutex().destroy()
409412
}
410413

411414
/// Return the childen data of the given node.
@@ -431,8 +434,8 @@ final class SyntaxDataArena: @unchecked Sendable {
431434
return SyntaxDataReferenceBuffer(UnsafeBufferPointer(start: baseAddress, count: childCount))
432435
}
433436

434-
mutex.lock()
435-
defer { mutex.unlock() }
437+
mutex().lock()
438+
defer { mutex().unlock() }
436439

437440
// Recheck, maybe some other thread has populated the buffer during acquiring the lock.
438441
if let baseAddress = swiftsyntax_atomic_pointer_get(baseAddressRef)?.assumingMemoryBound(

0 commit comments

Comments
 (0)