Reborrow &mut as &

Hi! Is it possible to somehow "reborrow" &mut T as &T? Like:

fn main() {
    let mut s = String::from("asdasd");
    let m1: &mut String = &mut s;
    
    let s1: &String = m1;
    drop(m1);                           // error here
    let s2: &String = s1;
    //let s3: &String = & s;

    assert_eq!(s1, "asdasd");
    assert_eq!(s2, "asdasd");
    //assert_eq!(s3, "asdasd");
}

Whenever a mutable reference is used, the borrow checker ends the lifetimes of all references derived from it; the reference must always remain exclusive. So when you pass m1 to drop(), this ends the lifetime of s1.

If the drop(m1) is removed and the s3 lines are uncommented, this still results in an error. The creation of s3 ends the lifetime of m1, since otherwise m1 would no longer be exclusive. By extension, it ends the lifetimes of s1 and s2, since you can't produce a longer-lived reference from a shorter-lived one.

So you can reborrow &mut T as &T, but the borrow checker won't forget that it came from a &mut T.

See also,

4 Likes