Problems - hard to describe


(Kenny Leung) #1

Hi All.

My problems are so weird that I don’t even know what to put in the subject line.

I’m using the latest Swift 3 snapshot, and I’m trying to write a bridge from [String] to (const char * const *)

Here’s my code:

public struct ArrayBridge<SwiftType,CType> {

    let originals :[SwiftType]
    let translated :[CType]
    //let pointers :[UnsafePointer<CType>?]

    init(array :[SwiftType], transform: @noescape (SwiftType) throws -> CType) throws {
        self.originals = array
        self.translated = try array.map(transform)
        let pointerArray = self.translated.map {
            guard let result = UnsafePointer<CType>($0) else {
                fatalError()
            }
            return result
        }
    }
}

This gives the error:

    Expression type '[_]' is ambiguous without more context
or Ambigious reference to member ‘map'

on the line “let pointerArray = self.translated.map {"

Some digging says that this may be helped if I explicitly specify the return type for the closure:

public struct ArrayBridge<SwiftType,CType> {

    let originals :[SwiftType]
    let translated :[CType]
    //let pointers :[UnsafePointer<CType>?]

    init(array :[SwiftType], transform: @noescape (SwiftType) throws -> CType) throws {
        self.originals = array
        self.translated = try array.map(transform)
        let pointerArray = self.translated.map { item -> UnsafePointer<CType> in
            guard let result = UnsafePointer<CType>(item) else {
                fatalError()
            }
            return result
        }
    }
}

This gives the error:

    Cannot invoke initializer for type 'UnsafePointer<CType>' with an argument list of type '((CType))’

on the line “ guard let result = UnsafePointer<CType>(item) else {“

Can anyone shed some light on this? What is a type with parentheses around it? I’ve also gotten errors like, “argument (_) -> _ does not match _ -> _”

Thanks!

-Kenny


(Kenny Leung) #2

Hi All.

I fixed my Problems. It turns out I had the declaration typed wrong. CType should have been CChar instead of [CChar]. The working version is this:

public struct ArrayBridge<SwiftType,CType> {

    let originals :[SwiftType]
    let translated :[[CType]]
    let pointers :[UnsafePointer<CType>?]
    public let pointer :UnsafePointer<UnsafePointer<CType>?>

    init(array :[SwiftType], transform: @noescape (SwiftType) throws -> [CType]) throws {
        self.originals = array
        self.translated = try array.map(transform)

        var pointers = [UnsafePointer<CType>?]()
        for item in translated {
            pointers.append(UnsafePointer<CType>(item))
        }
        pointers.append(nil)

        self.pointers = pointers
        self.pointer = UnsafePointer(self.pointers)
    }
}

-Kenny


(Joe Groff) #3

Glad to hear you were able to work your problem out. If you have time, we'd still appreciate a bug report about the unhelpful type error message.

-Joe

···

On Jun 24, 2016, at 12:17 PM, Kenny Leung via swift-users <swift-users@swift.org> wrote:

Hi All.

I fixed my Problems. It turns out I had the declaration typed wrong. CType should have been CChar instead of [CChar]. The working version is this:

public struct ArrayBridge<SwiftType,CType> {

    let originals :[SwiftType]
    let translated :[[CType]]
    let pointers :[UnsafePointer<CType>?]
    public let pointer :UnsafePointer<UnsafePointer<CType>?>

    init(array :[SwiftType], transform: @noescape (SwiftType) throws -> [CType]) throws {
        self.originals = array
        self.translated = try array.map(transform)

        var pointers = [UnsafePointer<CType>?]()
        for item in translated {
            pointers.append(UnsafePointer<CType>(item))
        }
        pointers.append(nil)

        self.pointers = pointers
        self.pointer = UnsafePointer(self.pointers)
    }
}


(Kenny Leung) #4

Filed as SR-1900

-Kenny