Error code E0387

Note: this error code is no longer emitted by the compiler.

This error occurs when an attempt is made to mutate or mutably reference data that a closure has captured immutably.

Erroneous code example:

#![allow(unused)]
fn main() {
// Accepts a function or a closure that captures its environment immutably.
// Closures passed to foo will not be able to mutate their closed-over state.
fn foo<F: Fn()>(f: F) { }

// Attempts to mutate closed-over data. Error message reads:
// `cannot assign to data in a captured outer variable...`
fn mutable() {
    let mut x = 0u32;
    foo(|| x = 2);
}

// Attempts to take a mutable reference to closed-over data. Error message
// reads: `cannot borrow data mutably in a captured outer variable...`
fn mut_addr() {
    let mut x = 0u32;
    foo(|| { let y = &mut x; });
}
}

The problem here is that foo is defined as accepting a parameter of type Fn. Closures passed into foo will thus be inferred to be of type Fn, meaning that they capture their context immutably.

If the definition of foo is under your control, the simplest solution is to capture the data mutably. This can be done by defining foo to take FnMut rather than Fn:

#![allow(unused)]
fn main() {
fn foo<F: FnMut()>(f: F) { }
}

Alternatively, we can consider using the Cell and RefCell types to achieve interior mutability through a shared reference. Our example's mutable function could be redefined as below:

#![allow(unused)]
fn main() {
use std::cell::Cell;

fn foo<F: Fn()>(f: F) { }

fn mutable() {
    let x = Cell::new(0u32);
    foo(|| x.set(2));
}
}

You can read more in the API documentation for Cell.