Reborrow a nested mutable reference

Viewed 61

I am trying to create a mutable reference to a mutable reference, drop the outer reference, then reuse the inner reference. However, I always get some kind of error. Here is a somewhat minimized, very verbose example of the problem:

#[derive(Clone, Debug)]
struct NoCopy;

fn foo<'a>(vec: &'a mut Vec<NoCopy>) -> &'a mut NoCopy {
    {
        let try_first: Option<&'a mut NoCopy> = vec.first_mut();
        if let Some(first) = try_first {
            return first;
        }
    }

    vec.push(NoCopy);
    vec.first_mut().unwrap()
}

Playground

This gives the following errors:

error[E0499]: cannot borrow `*vec` as mutable more than once at a time
  --> src/lib.rs:12:5
   |
4  | fn foo<'a>(vec: &'a mut Vec<NoCopy>) -> &'a mut NoCopy {
   |        -- lifetime `'a` defined here
5  |     {
6  |         let try_first: Option<&'a mut NoCopy> = vec.first_mut();
   |                        ----------------------   --- first mutable borrow occurs here
   |                        |
   |                        type annotation requires that `*vec` is borrowed for `'a`
...
12 |     vec.push(NoCopy);
   |     ^^^ second mutable borrow occurs here

error[E0499]: cannot borrow `*vec` as mutable more than once at a time
  --> src/lib.rs:13:5
   |
4  | fn foo<'a>(vec: &'a mut Vec<NoCopy>) -> &'a mut NoCopy {
   |        -- lifetime `'a` defined here
5  |     {
6  |         let try_first: Option<&'a mut NoCopy> = vec.first_mut();
   |                        ----------------------   --- first mutable borrow occurs here
   |                        |
   |                        type annotation requires that `*vec` is borrowed for `'a`
...
13 |     vec.first_mut().unwrap()
   |     ^^^ second mutable borrow occurs here

No matter what I try, I cannot seem to get this to compile. I thought that this issue could be related to Why can't I reuse a &mut reference after passing it to a function that accepts a generic type?, but I cannot figure out how to apply the accepted solution to this problem. This makes me wonder if the error is actually correct behavior (i.e. my code would be unsafe), but I cannot seem to figure out any problem with the code.

How do I get this code to compile, or is the compiler error caused by an actual logical problem?

0 Answers
Related