0
fn main() {
    let mut s = String::from("hello");
    let mut f = Foo(&mut s);
    let r = &mut f;
    run(r);
    println!("{:?}", f); // cannot borrow `f` as immutable ...
                         // but println!("{}", s); works fine
}

#[derive(Debug)]
struct Foo<'a>(&'a mut String);
fn run<'a, 'b: 'a>(_: &'b mut Foo<'a>) {}

It's not a real problem, is just something I found and I'm curious about

Why can't I use f after passing its mutable reference to run?
I know 'b: 'a is causing the error, and it probably never makes sense for the reference to live longer than the bounds of the parameter, but what is happening?
And why I can use s if theoretically it is borrowed by f that is borrowed by something?

  • 2
    The bound `'b: 'a` forces the lifetimes to be the same since everything inside has to live as long as `'b` as well. See [why explicit lifetime annotions trigger double mutable borrow errors](https://stackoverflow.com/questions/76669887/why-explicit-lifetime-annotions-trigger-double-mutable-borrow-errors) – cafce25 Aug 18 '23 at 11:47
  • Got it, and because there is no other references `f`, `s` is free to be used. – Alan Alves de Oliveira Aug 18 '23 at 12:01
  • 1
    The bound that you get automatically is `'a: 'b` (to be read "`'a` outlives `'b`" or `'a` lives longer than `'b`). By adding the symmetric bound `'b: 'a`, you force `'a = 'b`. – jthulhu Aug 18 '23 at 15:25

0 Answers0