3

How do I modify a variable that's defined outside of a closure from inside of a closure?

Code:

fn main() {
    let mut t = "foo".to_string();
    println!("{}", t);

    let mut closure = | | {
        t.clear();
    };
    closure();

    println!("{}", t);
}

Compilation Error:

cannot borrow `t` as immutable because it is also borrowed as mutable [--explain E0502]
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Michael
  • 34,873
  • 17
  • 75
  • 109
  • FYI, the code successfully compiles with recent versions of the Rust compiler. I believe this is due to [Non-Lexical lifetimes](https://stackoverflow.com/questions/50251487/what-are-non-lexical-lifetimes) – jmrah Nov 07 '19 at 01:09

1 Answers1

3

Exactly as you have done; that's not the problem here. The complete error message shows more detail:

error: cannot borrow `t` as immutable because it is also borrowed as mutable [--explain E0502]
    |>         let mut closure = || {
    |>                           -- mutable borrow occurs here
    |>             t.clear();
    |>             - previous borrow occurs due to use of `t` in closure
...
    |>     println!("{}", t);
    |>                    ^ immutable borrow occurs here
    |> }
    |> - mutable borrow ends here

You have given a mutable reference of the variable to the closure and the closure is still in scope. This means it retains the reference and you are not able to have any other references to the variable. This shows the same problem:

fn main() {
    let mut t = "foo".to_string();
    println!("> {}", t);
    let not_a_closure = &mut t;
    println!("> {}", t);
}

Creating the closure in a smaller scope forces the closure to go out of scope and release the reference before the call to println!:

fn main() {
    let mut t = "foo".to_string();
    println!("> {}", t);

    {
        let mut closure = || {
            t.clear();
        };
        closure();
    }

    println!("> {}", t);
}

I'd suggest looking at the 60+ other questions with the same error message for more information on the error.

Community
  • 1
  • 1
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366