Description
Description
The code below defines a struct, ClosureStorer
, that accepts a closure as an initialization argument. The class UsesStorers
creates two of these structs, one with <
as an argument and the other with >
. The problem is that both structs end up sharing a reference to the same closure.
I suspect that the underlying issue lies somewhere in the domain of class initialization. If the line
let greater = ClosureStorer(>), lessThan = ClosureStorer(<)
is rewritten to
let greater = ClosureStorer(>)
let lessThan = ClosureStorer(<)
then the problem does not occur.
Other cases where the problem doesn't occur:
- If the ClosureStorers are initialized at the top level rather than inside a class definition.
- If the arguments to ClosureStorer() are the names of freestanding functions rather than operators.
Reproduction
Run the following code:
struct ClosureStorer {
let op: (Int, Int) -> Bool
init(_ op: @escaping (Int, Int) -> Bool) {
self.op = op
}
func compare(_ a: Int, _ b: Int) -> Bool {
return op(a, b)
}
}
class UsesStorers {
let greater = ClosureStorer(>), lessThan = ClosureStorer(<)
func test() {
print(greater.compare(1, 2), lessThan.compare(1, 2)) // false false
print(greater.compare(2, 1), lessThan.compare(2, 1)) // true true
}
}
let user = UsesStorers()
user.test()
As indicated in the comments, the two ClosureStorer structs return (or should return, if the issue is being demonstrated correctly) the same comparison results.
Xcode shows ClosureStorer.op
as having the same address for both copies of the struct. The debug output labels this "implicit closure #1".
Expected behavior
The two ClosureStorer structs are independent and should each return results that conform to the comparison operator they're initialized with. The correct output is "false true / true false", demonstrating that the closures return different results.
Environment
I'm seeing this problem on Xcode 16.2 (16C5032a), which I believe is Swift 6.0.3.
Additional information
No response