Capture mutable reference in function without Copy trait

I would like to run the following code, but the compiler complains that

error[E0382]: use of moved value: `f`
 --> src\main.rs:8:21
  |
1 | fn add<F>(a: u32, f: F) -> u32
  |                   - move occurs because `f` has type `F`, which does not implement the `Copy` trait
...
7 |     acc += a + add2(f);
  |                     - value moved here
8 |     acc += a + add2(f);
  |                     ^ value used here after move
  |
help: consider further restricting this bound
  |
3 |     F: FnMut(u32) -> u32 + Copy,
  |                          ^^^^^^

But, while I add Copy trait, Now I need a impl for &mut i32,
While there might be lots of struct that dont implement Copy, which is terrible.
Is there any other solution without Copy trait?

error[E0277]: the trait bound `&mut i32: std::marker::Copy` is not satisfied in `[closure@src\main.rs:24:24: 27:10 count:&mut i32]`
  --> src\main.rs:24:15
   |
1  |   fn add<F>(a: u32, f: F) -> u32
   |      --- required by a bound in this
...
4  |       F: Copy,
   |          ---- required by this bound in `add`
...
24 |           num = add(num, |p| {
   |  _______________^^^______-
   | |               |
   | |               within `[closure@src\main.rs:24:24: 27:10 count:&mut i32]`, the trait `std::marker::Copy` is not implemented for `&mut i32`
25 | |             count += 1;
26 | |             p * 2
27 | |         });
   | |_________- within this `[closure@src\main.rs:24:24: 27:10 count:&mut i32]`
   |
   = help: the following implementations were found:
             <i32 as std::marker::Copy>
   = note: `std::marker::Copy` is implemented for `&i32`, but not for `&mut i32`
   = note: required because it appears within the type `[closure@src\main.rs:24:24: 27:10 count:&mut i32]`

An example.

fn add<F>(a: u32, f: F) -> u32
where
    F: FnMut(u32) -> u32,
    F: Copy,
{
    let mut acc = 0;
    acc += a + add2(f);
    acc += a + add2(f);
    acc
}

fn add2<F>(mut f: F) -> u32
where
    F: FnMut(u32) -> u32,
{
    let p = 10;
    f(p)
}

fn main() {
    let mut num = 1;
    let mut count = 0;
    for _ in 0..10 {
        num = add(num, |p| {
            count += 1;
            p * 2
        });
    }
    println!("{:?}", (num, count));
}

You can simply pass &mut f to add2, since exclusive reference to FnMut are FnMut too - playground:

fn add<F>(a: u32, mut f: F) -> u32
where
    F: FnMut(u32) -> u32
{
    let mut acc = 0;
    acc += a + add2(&mut f);
    acc += a + add2(&mut f);
    acc
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.