From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- .../rustc_error_codes/src/error_codes/E0387.md | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 compiler/rustc_error_codes/src/error_codes/E0387.md (limited to 'compiler/rustc_error_codes/src/error_codes/E0387.md') diff --git a/compiler/rustc_error_codes/src/error_codes/E0387.md b/compiler/rustc_error_codes/src/error_codes/E0387.md new file mode 100644 index 000000000..38ad19bd6 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0387.md @@ -0,0 +1,57 @@ +#### 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: + +```compile_fail +// 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: 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: + +``` +fn foo(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: + +``` +use std::cell::Cell; + +fn foo(f: F) { } + +fn mutable() { + let x = Cell::new(0u32); + foo(|| x.set(2)); +} +``` + +You can read more in the API documentation for [Cell][std-cell]. + +[std-cell]: https://doc.rust-lang.org/std/cell/ -- cgit v1.2.3