9

I'm using the Swift-VectorBoolean library, which is currently on Swift 3.2, not yet updated for Swift 4.2, but should still work on Xcode 10. Running this on Xcode 9, it works fine. On Xcode 10, it gives an error that I'm not sure how to fix. This is the function in question:

typealias MyPathApplier = @convention(block) (UnsafePointer<CGPathElement>) -> Void
// Note: You must declare MyPathApplier as @convention(block), because
// if you don't, you get "fatal error: can't unsafeBitCast between
// types of different sizes" at runtime, on Mac OS X at least.

private func myPathApply(_ path: CGPath!, block: MyPathApplier) {
  let callback: @convention(c) (UnsafeMutableRawPointer, UnsafePointer<CGPathElement>) -> Void = { (info, element) in
    let block = unsafeBitCast(info, to: MyPathApplier.self)
    block(element)
  }

  path.apply(info: unsafeBitCast(block, to: UnsafeMutableRawPointer.self), function: unsafeBitCast(callback, to: CGPathApplierFunction.self))
}

The error is on that last line, path.apply, highlighting the first unsafeBitCast:

Converting non-escaping value to 'T' may allow it to escape

I'm not sure how to modify this code to remove the error, or if this is an issue with Xcode 10. It should be able to compile Xcode 3.2 code.. even updating the code base to Swift 4 in Xcode 9, it still has the same issue.

EDIT: Changing this with the answer from @Vyacheslav allows it to compile, but it gets a runtime error: "Fatal error: Can't unsafeBitCast between types of different sizes"

There is a comment provided above the function which I didn't include in the sample above:

// Note: You must declare MyPathApplier as @convention(block), because
// if you don't, you get "fatal error: can't unsafeBitCast between
// types of different sizes" at runtime, on Mac OS X at least.

I still don't understand what needs to change here to ensure it builds, and we also don't get a runtime error.

Andrew
  • 6,993
  • 10
  • 39
  • 72

1 Answers1

21

Use

private func myPathApply(_ path: CGPath!, 
    block: @escaping @convention(block) (UnsafePointer<CGPathElement>) -> Void) {

}

@noescape is now by default

SymbolixAU
  • 22,021
  • 4
  • 47
  • 120
Vyacheslav
  • 23,112
  • 16
  • 96
  • 174
  • This allows it to compile, but now I'm facing a runtime error. Added detail to the question. – Andrew Jul 29 '18 at 10:26