Mutable borrow not releasing when struct that captured it goes out of scope

⚓ Rust    📅 2025-08-10    👤 surdeus    👁️ 5      

surdeus

I'm trying to create a stack of environments (like when implementing an interpreter or compiler) where each Env has a reference to its parent, and a child Env should never outlive its parent. (And an Env will always have at most one child.)

I have the following code, but for some reason the compiler doesn't release the parent Env when the first child Env goes out of scope. How do I make this work? (Preferably without a cop-out solution like Rc<RefCell<>>)

struct Env<'a> {
    parent: Option<&'a mut Env<'a>>,
}

fn main() {
    let mut parent_env = Env{parent: None};
    
    // This works:
    {
        let child_env_1 = Env{
            parent: Some(&mut parent_env)
        };
        _ = child_env_1;
    }
    
    // But doing it a second time doesn't work:
    {
        // At this point, child_env_1 should have went out of scope
        // and released the mutable reference to parent_env, no?
        // Why does the compiler think parent_env is still borrowed?
        let child_env_2 = Env{
            parent: Some(&mut parent_env)
        };
        _ = child_env_2; 
    }
}

Rust playground:

Error:

  Compiling playground v0.0.1 (/playground)
error[E0499]: cannot borrow `parent_env` as mutable more than once at a time
  --> src/main.rs:22:26
   |
11 |             parent: Some(&mut parent_env)
   |                          --------------- first mutable borrow occurs here
...
22 |             parent: Some(&mut parent_env)
   |                          ^^^^^^^^^^^^^^^
   |                          |
   |                          second mutable borrow occurs here
   |                          first borrow later used here

For more information about this error, try `rustc --explain E0499`.
error: could not compile `playground` (bin "playground") due to 1 previous error

8 posts - 6 participants

Read full topic

🏷️ Rust_feed