Skip to content

Commit aa32c4a

Browse files
dgrove-ossdas
authored andcommitted
SR-3477: replace unsafeBitCast by withoutActuallyEscaping
Now that withoutActuallyEscaping is implemented, use it instead of unsafeBitCast to allow passing a closure capturing a non-escaping block down to the C implementation of dispatch_data_apply (which does not actually escape its block argument). Signed-off-by: Daniel A. Steffen <dsteffen@apple.com>
1 parent e87f490 commit aa32c4a

File tree

1 file changed

+12
-10
lines changed

1 file changed

+12
-10
lines changed

src/swift/Data.swift

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,18 @@ public struct DispatchData : RandomAccessCollection {
9191
public func enumerateBytes(
9292
block: @noescape (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Int, _ stop: inout Bool) -> Void)
9393
{
94-
// FIXME: When SR-2313 (withoutActuallyEscaping) is implemented, use it to replace unsafeBitCast
95-
let nonEscapingBlock = unsafeBitCast(block, to: _enumerateBytesBlock.self)
96-
_ = CDispatch.dispatch_data_apply(__wrapped.__wrapped) { (_, offset: Int, ptr: UnsafeRawPointer, size: Int) in
97-
let bytePtr = ptr.bindMemory(to: UInt8.self, capacity: size)
98-
let bp = UnsafeBufferPointer(start: bytePtr, count: size)
99-
var stop = false
100-
nonEscapingBlock(bp, offset, &stop)
101-
return !stop
94+
// we know that capturing block in the closure being created/passed to dispatch_data_apply
95+
// does not cause block to escape because dispatch_data_apply does not allow its
96+
// block argument to escape. Therefore, the usage of withoutActuallyEscaping to
97+
// bypass the Swift type system is safe.
98+
withoutActuallyEscaping(block) { escapableBlock in
99+
_ = CDispatch.dispatch_data_apply(__wrapped.__wrapped) { (_, offset: Int, ptr: UnsafeRawPointer, size: Int) in
100+
let bytePtr = ptr.bindMemory(to: UInt8.self, capacity: size)
101+
let bp = UnsafeBufferPointer(start: bytePtr, count: size)
102+
var stop = false
103+
escapableBlock(bp, offset, &stop)
104+
return !stop
105+
}
102106
}
103107
}
104108

@@ -276,8 +280,6 @@ public struct DispatchDataIterator : IteratorProtocol, Sequence {
276280
internal var _position: DispatchData.Index
277281
}
278282

279-
typealias _enumerateBytesBlock = (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Int, _ stop: inout Bool) -> Void
280-
281283
@_silgen_name("_swift_dispatch_data_empty")
282284
internal func _swift_dispatch_data_empty() -> dispatch_data_t
283285

0 commit comments

Comments
 (0)