Merge pull request #198 from dgrove-oss/SR-3477

SR-3477: replace unsafeBitCast by withoutActuallyEscaping
diff --git a/src/swift/Data.swift b/src/swift/Data.swift
index fc0bc09..d51205c 100644
--- a/src/swift/Data.swift
+++ b/src/swift/Data.swift
@@ -91,14 +91,18 @@
 	public func enumerateBytes(
 		block: (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Int, _ stop: inout Bool) -> Void) 
 	{
-		// FIXME: When SR-2313 (withoutActuallyEscaping) is implemented, use it to replace unsafeBitCast
-		let nonEscapingBlock = unsafeBitCast(block, to: _enumerateBytesBlock.self)
-		_ = CDispatch.dispatch_data_apply(__wrapped.__wrapped) { (_, offset: Int, ptr: UnsafeRawPointer, size: Int) in
-			let bytePtr = ptr.bindMemory(to: UInt8.self, capacity: size)
-			let bp = UnsafeBufferPointer(start: bytePtr, count: size)
-			var stop = false
-			nonEscapingBlock(bp, offset, &stop)
-			return !stop
+		// we know that capturing block in the closure being created/passed to dispatch_data_apply
+		// does not cause block to escape because dispatch_data_apply does not allow its
+		// block argument to escape.  Therefore, the usage of withoutActuallyEscaping to
+		// bypass the Swift type system is safe.
+		withoutActuallyEscaping(block) { escapableBlock in
+			_ = CDispatch.dispatch_data_apply(__wrapped.__wrapped) { (_, offset: Int, ptr: UnsafeRawPointer, size: Int) in
+				let bytePtr = ptr.bindMemory(to: UInt8.self, capacity: size)
+				let bp = UnsafeBufferPointer(start: bytePtr, count: size)
+				var stop = false
+				escapableBlock(bp, offset, &stop)
+				return !stop
+			}
 		}
 	}
 
@@ -273,8 +277,6 @@
 	internal var _position: DispatchData.Index
 }
 
-typealias _enumerateBytesBlock = (_ buffer: UnsafeBufferPointer<UInt8>, _ byteIndex: Int, _ stop: inout Bool) -> Void
-
 @_silgen_name("_swift_dispatch_data_empty")
 internal func _swift_dispatch_data_empty() -> dispatch_data_t