Data withUnsafeBytes

Hi guys,

I’m either missing a subtlety in regards to closures or I found a bug with the type inference system in Xcode 8 Beta 6. Thought I’d run it by you.

I’m trying to use Data’s method withUnsafeBytes(_:). It’s declared as:

func withUnsafeBytes<ResultType, ContentType>(_ body: (UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType

The Swift Language book states that closure syntax uses the following form:

{ (parameters) -> returntype in
    statements
}

So, at the most basic implementation, I tried the following:

let tryThis = items.withUnsafeBytes {
    (bytes) -> Int in
    
    return 1
}

And I get the error Declared closure result 'Int' is incompatible with contextual type ‘ResultType’.

Xcode suggests I change Int to ResultType, but that just gives me the error that I’m using an undeclared type.

Am I getting the syntax wrong or Xcode getting confused?

Thanks a lot.

···


Chris McIntyre

The compiler has no way of inferring the type of the generic ContentType parameter because you're not using that parameter anywhere in the body of the closure that could give the compiler a hint. So you have to provide the type manually by explicitly annotating the type of the closure's parameter.

For example, if you want to treat `items` as a series of `UInt8` values:

     let tryThis = items.withUnsafeBytes {
         (bytes: UnsafePointer<UInt8>) -> Int in
         return 1
     }

I agree the compiler diagnostic should probably be better, though.

Ole

That makes sense. I think I've gotten so used to the type system magically figuring out what I want, combined with the error message pointing to the return type that this just went right over my head.

···

--
Chris McIntyre

On Sep 4, 2016, at 3:59 PM, Ole Begemann via swift-users <swift-users@swift.org> wrote:

The compiler has no way of inferring the type of the generic ContentType parameter because you're not using that parameter anywhere in the body of the closure that could give the compiler a hint. So you have to provide the type manually by explicitly annotating the type of the closure's parameter.

For example, if you want to treat `items` as a series of `UInt8` values:

   let tryThis = items.withUnsafeBytes {
       (bytes: UnsafePointer<UInt8>) -> Int in
       return 1
   }

I agree the compiler diagnostic should probably be better, though.

Ole

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users