A couple times recently I've run into situations where this doesn't compile:
foo.frobnicate(bar.mutatingFunc)
but then this does:
foo.frobnicate { bar.mutatingFunc() }
If the second is allowed, why not the first?
A couple times recently I've run into situations where this doesn't compile:
foo.frobnicate(bar.mutatingFunc)
but then this does:
foo.frobnicate { bar.mutatingFunc() }
If the second is allowed, why not the first?
I can reproduce the issue in Xcode 15.0.
struct Foo {
// It takes a non-escaping closure
func run(_ c: () -> Void) {
c()
}
}
struct Bar {
var x: Int = 1
mutating func mutate() {
x = 2
}
}
func test() {
let foo = Foo()
var bar = Bar()
// test 1: this works
foo.run {
bar.mutate()
}
// test 2: this doesn't work
// Error: Escaping autoclosure captures 'inout' parameter 'self'
foo.run(bar.mutate)
}
There are two things odd:
The "self" in the error message. I suspect it should be "bar" instead?
Foo.run()
takes a non-escaping closure, but the compiler generates an escaping autoclosure (and hence the error).
Maybe it's a bug?
Off-topic...a comment on the terminology. I think bar.mutate
is a function, not a partially applied function. I don't think Swift has language level support for partially applied function.
Allowing this in non-escaping position seems reasonable to me (unless I’m missing something), and regardless that error message should be better.
Interestingly up until Swift 5.5 godbolt gave me this wording:
error: partial application of 'mutating' method is not allowed
you are right, "partial application" / currying is the term of art for something else we don't have in swift.
It is partial application if you think of self
as an argument. It’s not general partial application, though.
Where's self in the above example?
bar
, that would be self
inside the body of mutate
if this were allowed.