Hi,
With the following code:
(See also in the playground here)
fn main() {
let mut drop_counter = 0;
struct IntWrap<F> (u32, Box<F>) where F : FnMut();
impl<F> Drop for IntWrap<F> where F : FnMut() {
fn drop(&mut self) {
self.1();
}
}
{
let mut increase = || { drop_counter += 1; };
let i1 = IntWrap(3, Box::new(&increase));
let i2 = IntWrap(2, Box::new(&increase));
}
println!("drop_counter={}", drop_counter);
}
I get:
error[E0525]: expected a closure that implements the `Fn` trait, but this closure only implements `FnMut`
--> src/main.rs:11:28
|
11 | let mut increase = || { drop_counter += 1; };
| ^^ ------------ closure is `FnMut` because it mutates the variable `drop_counter` here
| |
| this closure implements `FnMut`, not `Fn`
12 | let i1 = IntWrap(3, Box::new(&increase));
| ------- the requirement to implement `Fn` derives from here
Motivation:
I want to count the number of times all instances of a struct was dropped, in order to ensure I'm not creating circular references (actual code is much more complicated). It's part of a unit test, not "real" code, and I've simplified it here.
But I can't figure out how to do it. The way I tried above is by saving a closure inside the struct, where the closure increases the counter.
I think the problem is that, since the closure is mutating the environment, I can't use it more than once, no matter what I do. Which means that what I want to do can't be done at all. Which is sad .
But... I could be wrong. But then again the error message isn't helping much and looks like a bug. I mean, I've clearly stated that F implements FnMut, and yet somehow there's a requirement (due to IntWrap, says the error message??) that the closure implements Fn.