12

When compiling the following code:

fn main() {
    let mut fields = Vec::new();
    let pusher = &mut |a: &str| {
        fields.push(a);
    };
}

The compiler gives me the following error:

error: borrowed data cannot be stored outside of its closure
 --> src/main.rs:4:21
  |
3 |     let pusher = &mut |a: &str| {
  |         ------        --------- ...because it cannot outlive this closure
  |         |
  |         borrowed data cannot be stored into here...
4 |         fields.push(a);
  |                     ^ cannot be stored outside of its closure

And in later versions of Rust:

error[E0521]: borrowed data escapes outside of closure
 --> src/main.rs:4:9
  |
2 |     let mut fields = Vec::new();
  |         ---------- `fields` declared here, outside of the closure body
3 |     let pusher = &mut |a: &str| {
  |                        - `a` is a reference that is only valid in the closure body
4 |         fields.push(a);
  |         ^^^^^^^^^^^^^^ `a` escapes the closure body here

What does this error mean, and how can I fix my code?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Valentin Lorentz
  • 9,556
  • 6
  • 47
  • 69

1 Answers1

11

It means exactly what it says: that the data you are borrowing only lives for the duration of the closure. Attempting to store it outside of the closure would expose the code to memory unsafety.

This arises because the inferred lifetime of the closure's argument has no relation to the lifetimes stored in the Vec.

Generally, this isn't a problem you experience because something has caused more type inference to happen. In this case, you can add a type to fields and remove it from the closure:

let mut fields: Vec<&str> = Vec::new();
let pusher = |a| fields.push(a);
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Oh, thank you! I would have expected an error telling me the borrowchk does not have enough info. – Valentin Lorentz Jun 30 '18 at 22:40
  • @ValentinLorentz FWIW, I've never seen this particular error before, and this is the first SO question about it. It's possible this is a brand new error. You may wish to [file a bug](https://github.com/rust-lang/rust) with your case and the error message and say that it wasn't helpful. The Rust contributors strive to have useful error messages. – Shepmaster Jul 01 '18 at 03:36
  • I spent a few hours misinterpreting the "and remove it from the closure" part. It's not that you can remove it if you're bored with it, you _have to_ remove it to make this compile. – Stein Aug 08 '20 at 19:34