tierriminator
tierriminator

Reputation: 649

Swift: compile-time error with optional chaining and nil-coalescing

I have a strange problem with optional chaining and nil-coalescing in Swift. Can anyone explain why the following code won't compile:

class A<T> {
    var val: T
    var x: A<T>?
    var y: A<T>?
    init(t:T){
        val = t
    }
    func test() -> [T] {
        return (self.x?.test() ?? []) + [val] + (self.y?.test() ?? [])
    }
}

But when writing

func test() -> [T] {
    return (self.x?.test() ?? []) + ([val] + (self.y?.test() ?? []))
}

It does? The error says:

Cannot convert value of type '[T]?' to expected argument type '[_]?'

For me it looks a lot like a compiler bug.

Upvotes: 3

Views: 263

Answers (1)

Sulthan
Sulthan

Reputation: 130092

Type inferring is hard with complicated expressions. That [_] usually means that type is unknown - could not be inferred. Simplifying the expression solves the problem in 99% of the time:

class A<T> {
    var val: T
    var x: A<T>?
    var y: A<T>?
    init(t:T){
        val = t
    }
    func test() -> [T] {
        let xResult = self.x?.test() ?? []
        let yResult = self.y?.test() ?? []

        return xResult + [val] + yResult
    }
}

Another 99% of the time, type inferring problems can be solved by specifying a type explicitly:

return (self.x?.test() as [T]? ?? []) + [val] + (self.y?.test() ?? [])

You have found a workaround yourself. That workaround with parenthesis removes certain number of type inferring paths.

Reported as SR-4309

Upvotes: 3

Related Questions