3

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.

tierriminator
  • 587
  • 5
  • 19

1 Answers1

3

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

Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • This does provide a good solution to the problem. Perhaps the Swift team would still be interested in seeing the bit of problematic code posted above, though I doubt it would be high priority, if priority at all, such that it would eventually be addressed. – Michael Fourre Mar 21 '17 at 19:45
  • 1
    @MichaelFourre I think a similar problem has been already reported many many times. I remember the questions here on SO. This expression is actually quite simple, all the variables are well defined in scope, there should be no room for inferring problems. It's probably the concatenation with operators that is the root cause. – Sulthan Mar 21 '17 at 19:55
  • @MichaelFourre I went over the reported type inferring errors and I decided to report it in the end. – Sulthan Mar 21 '17 at 20:32