Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The FnMut trait in Rust represents a closure that can be called multiple times and may mutate its internal state. Rather than dictating how variables are captured from the environment, FnMut specifies the calling convention: it requires exclusive, mutable access (&mut self) to the closure’s environment during execution. A closure implements FnMut if its body requires mutable access to the captured environment, regardless of whether the variables are captured by mutable reference, captured by value (e.g., using the move keyword), or if the closure simply implements the more restrictive Fn trait (which automatically satisfies FnMut bounds).

Trait Signature

The FnMut trait is defined in the standard library as a subtrait of FnOnce:
pub trait FnMut<Args>: FnOnce<Args> {
    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
}
Because the call_mut method takes &mut self, the closure instance itself must be bound as mutable (let mut) to be executed. The &mut self signature guarantees that the closure cannot be invoked concurrently, preventing data races on the captured state.

Syntax and Mechanics

When a closure mutates a variable from its environment, the compiler infers the FnMut trait.
let mut state = 0;

// The closure binding `mutate_state` must be declared `mut` 
// because invoking it requires a mutable borrow of the closure struct.
let mut mutate_state = || {
    state += 1; 
};

mutate_state();
mutate_state();

Capture Modes

The FnMut trait is orthogonal to the capture mode. A closure can implement FnMut while capturing data by value. If the move keyword is used, the closure takes ownership of the variables, but it still implements FnMut if it mutates that owned data internally:
let mut state = 0;

// Captures `state` by value (i32) due to `move`.
// Implements `FnMut` because it mutates its owned internal state.
let mut mutate_owned_state = move || {
    state += 1;
};

mutate_owned_state();

Compiler Desugaring

To understand the memory layout and trait resolution, a closure capturing by mutable reference is conceptually desugared by the compiler into an anonymous struct and the corresponding trait implementations. Because FnOnce is a supertrait of FnMut, the compiler must implement both:
// 1. The compiler generates an anonymous struct holding the captured environment.
struct AnonymousClosure<'a> {
    state: &'a mut i32,
}

// 2. FnOnce is implemented to define the Output type and allow by-value calls.
impl<'a> FnOnce<()> for AnonymousClosure<'a> {
    type Output = ();
    
    extern "rust-call" fn call_once(mut self, args: ()) -> Self::Output {
        *self.state += 1;
    }
}

// 3. FnMut is implemented, utilizing &mut self for repeated mutations.
impl<'a> FnMut<()> for AnonymousClosure<'a> {
    extern "rust-call" fn call_mut(&mut self, args: ()) -> Self::Output {
        *self.state += 1;
    }
}

Borrowing Rules and Non-Lexical Lifetimes

When an FnMut closure captures variables by mutable reference (&mut T), it strictly enforces Rust’s borrowing rules regarding exclusive access. You cannot borrow the captured variables directly (neither mutably nor immutably) while the closure’s borrow is active. However, due to Rust’s Non-Lexical Lifetimes (NLL), this exclusive mutable borrow lasts only until the closure’s last use in the control flow, not for the duration of its entire lexical scope. Once the closure is invoked for the final time and is no longer referenced, the borrow is released, and the original variables can be accessed again.

Trait Hierarchy

FnMut sits in the middle of Rust’s closure trait hierarchy: Fn -> FnMut -> FnOnce.
  • FnMut implies FnOnce: Because FnMut inherits from FnOnce, any closure that implements FnMut can be passed to a function expecting an FnOnce. It is guaranteed to be callable at least once.
  • Fn implies FnMut: Any closure that implements Fn (requiring only &self to execute) automatically satisfies FnMut bounds. A function requiring an FnMut parameter will accept an Fn closure, as an immutable environment trivially satisfies a mutable calling convention that simply performs no mutations.
Master Rust with Deep Grasping Methodology!Learn More