bbrk24
1
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?
1 Like
rayx
(Huan Xiong)
2
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.
2 Likes
Jumhyn
(Frederick Kellison-Linn)
3
Allowing this in non-escaping position seems reasonable to me (unless I’m missing something), and regardless that error message should be better.
tera
4
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.
1 Like
jrose
(Jordan Rose)
5
It is partial application if you think of self as an argument. It’s not general partial application, though.
3 Likes
tera
6
Where's self in the above example?
jrose
(Jordan Rose)
7
bar, that would be self inside the body of mutate if this were allowed.
1 Like