Reduce(into:): why cannot use `callAsFunction()` syntax: cannot use mutating member on immutable value: '$0' is immutable

struct Accumulator {
    var value = 0

    mutating func doIt(_ n: Int) {
        value += n
    }

    mutating func callAsFunction(_ n: Int) {
        doIt(n)
    }
}


let result1 = [1, 2, 3, 4].reduce(into: Accumulator()) {
    $0.doIt($1)     // 1) call mutating is fine here
}
.value


let result2 = [1, 2, 3, 4].reduce(into: Accumulator()) {
    $0($1)          // 2) error: cannot use mutating member on immutable value: '$0' is immutable
}
.value

Looks like a bug :thinking::thinking:.

1 Like

So it appears I cannot use the shorthand $0($1). It works if I explicitly declare the parameters:

let result2 = [1, 2, 3, 4].reduce(into: Accumulator()) { (a: inout Accumulator, n: Int) in
    a(n)
}
.value

but I think it should work with shorthand params, so you are right it's a bug? Should i file a bug report?

I got different error "type of expression is ambiguous without more context"
but $0.callAsFunction($1) fix the problem.

I'm using Xcode 12.5 b2 Xcode Playground, what are using?

Upon closer look, I got ambiguous type as well on Playground 3.4 (the iOS app).

I'm using Xcode Playground. But still, it's not "ambiguous", should work?

It should compile & run. If anything, it shouldn't behave too differently from $0.callAsFunction($1) (which compiles & runs).

1 Like

Version 12.4 (12D4e).

but as

said, it's so weird $0($1) != $0.callAsFunction($1) ...

1 Like

SR-14250: Using callAsFunction syntax on closure shorthand inout parameters do not compile

1 Like

Seems like it used to work in Swift 5.2 on Linux.

1 Like

Only 5.2 works

5.0, 5.1, 5.3, nightly fail with:

error: type of expression is ambiguous without more context
}.value

error is different for Xcode Version 12.5 beta 2 (12E5234g):

error: cannot use mutating member on immutable value: '$0' is immutable

1 Like

That's even stranger.

So it wasn't working, then in 5.2 work, then broken again, this seems to indicate there is no test case for this. Otherwise, this breakage would be noticed and not allow to go out broken.

Or these is test case, but the failure is ignored...