The following code produces the compile error "cannot borrow `*s` as immutable because it is also borrowed` as mutable":
#[derive(Debug)]
struct S {
a: usize,
}
fn do_stuff(s: &mut S) -> &usize {
let x = do_more_stuff(s); // Mutable borrow of `s`: `x` takes on same lifetime
// Immutable borrow of `s`: disallowed because mutable borrow is prolonged
// by later use of `x`
dbg!(s as &S);
x
}
fn do_more_stuff(s: &mut S) -> &usize {
s.a += 1;
&s.a
}
As far as I can see, in function do_stuff
, x
will have the same lifetime as s
, but once the &mut s
is dropped (thanks to non-lexical lifetimes), that lifetime should be only for the immutably-borrowed x
. So the second immutable borrow in the dbg!
call could logically be allowed.
For fun, I also tried this with rustc -Z polonius
, which gave the same error.
I can workaround this with unsafe
:
let x = do_more_stuff(unsafe { &mut *(s as *mut _) });
Is there a safe workaround which the compiler will accept?