]> git.proxmox.com Git - rustc.git/blame - src/librustc_error_codes/error_codes/E0387.md
New upstream version 1.47.0+dfsg1
[rustc.git] / src / librustc_error_codes / error_codes / E0387.md
CommitLineData
60c5eb7d
XL
1#### Note: this error code is no longer emitted by the compiler.
2
3This error occurs when an attempt is made to mutate or mutably reference data
4that a closure has captured immutably.
5
6Erroneous code example:
7
8```compile_fail
9// Accepts a function or a closure that captures its environment immutably.
10// Closures passed to foo will not be able to mutate their closed-over state.
11fn foo<F: Fn()>(f: F) { }
12
13// Attempts to mutate closed-over data. Error message reads:
14// `cannot assign to data in a captured outer variable...`
15fn mutable() {
16 let mut x = 0u32;
17 foo(|| x = 2);
18}
19
20// Attempts to take a mutable reference to closed-over data. Error message
21// reads: `cannot borrow data mutably in a captured outer variable...`
22fn mut_addr() {
23 let mut x = 0u32;
24 foo(|| { let y = &mut x; });
25}
26```
27
28The problem here is that foo is defined as accepting a parameter of type `Fn`.
29Closures passed into foo will thus be inferred to be of type `Fn`, meaning that
30they capture their context immutably.
31
32If the definition of `foo` is under your control, the simplest solution is to
33capture the data mutably. This can be done by defining `foo` to take FnMut
34rather than Fn:
35
36```
37fn foo<F: FnMut()>(f: F) { }
38```
39
40Alternatively, we can consider using the `Cell` and `RefCell` types to achieve
41interior mutability through a shared reference. Our example's `mutable`
42function could be redefined as below:
43
44```
45use std::cell::Cell;
46
47fn foo<F: Fn()>(f: F) { }
48
49fn mutable() {
50 let x = Cell::new(0u32);
51 foo(|| x.set(2));
52}
53```
54
74b04a01 55You can read more in the API documentation for [Cell][std-cell].
60c5eb7d 56
74b04a01 57[std-cell]: https://doc.rust-lang.org/std/cell/