Error

"expected a closure that implements Fn but this closure only implements FnOnce" — How to Fix

This error occurs because the function or trait you are passing the closure to requires it to be callable multiple times (`Fn`), but your closure captures a variable by move, making it callable only once (`FnOnce`).

This error occurs because the function or trait you are passing the closure to requires it to be callable multiple times (Fn), but your closure captures a variable by move, making it callable only once (FnOnce). To fix it, change the capture mode to borrow the variable (using & or &mut) instead of moving ownership, or restructure the code so the variable doesn't need to be moved into the closure.

The most common cause is capturing a non-Copy type (like a String or a custom struct) by value. When you do this, the closure takes ownership of that value. If the closure is called a second time, the value is already gone, violating the Fn contract.

Here is a practical example of the error and the fix:

fn apply_twice<F>(f: F, x: i32) 
where 
    F: Fn(i32) -> i32, // Requires Fn (callable multiple times)
{
    let result1 = f(x);
    let result2 = f(x); // Fails if f is FnOnce
    println!("Results: {}, {}", result1, result2);
}

fn main() {
    let data = String::from("hello");

    // ERROR: Captures `data` by move. After the first call, `data` is gone.
    // This closure only implements FnOnce, but `apply_twice` needs Fn.
    // let bad_closure = |x| { println!("{} {}", data, x); }; 
    // apply_twice(bad_closure, 1); 

    // FIX 1: Borrow the data instead of moving it.
    // This closure implements Fn because it only borrows `data`.
    let good_closure = |x| { println!("{} {}", data, x); };
    apply_twice(good_closure, 1);

    // FIX 2: If you must modify the captured variable, use a mutable reference.
    let mut counter = 0;
    let mut_counter_closure = |x| { 
        counter += 1; 
        println!("Count: {}, Input: {}", counter, x); 
    };
    // Note: This requires the function signature to accept FnMut instead of Fn
}

If you specifically need to move ownership into the closure (e.g., to consume a resource), you cannot use a function expecting Fn. You must change the function signature to accept FnOnce instead, or use a std::cell::RefCell or std::sync::Mutex to wrap the data if you need interior mutability.

For most cases, simply ensuring you capture by reference (&data) or mutable reference (&mut data) resolves the issue immediately. If the variable is a Copy type (like i32), Rust automatically copies it, so the closure naturally implements Fn. The error almost always points to a non-Copy type being moved by mistake.