struct Foo01<'a> {
    val: u32,
    str: &'a String,
}
fn mutate_and_share_01<'a>(foo: &'a mut Foo01<'a>) -> &'a Foo01<'a> {
    foo
}
fn mutate_and_share_02<'a>(foo: &'a mut Foo01<'a>) -> &'a Foo01 {
    foo
}
fn mutate_and_share_03<'a>(foo: &'a mut Foo01) -> &'a Foo01<'a> {
    foo
}
fn main() {
    let mut foo = Foo01 { val: 16, str: &String::from("Hello ") };
    let foo_mut = &mut foo;
    //let loan = mutate_and_share_01(foo_mut);
    //let loan2 = mutate_and_share_01(foo_mut); //error
    //let loan = mutate_and_share_02(foo_mut);
    //let loan2 = mutate_and_share_02(foo_mut); //error
    let loan = mutate_and_share_03(foo_mut);
    let loan2 = mutate_and_share_03(foo_mut); //good
}
What are differences between these mutate_and_share versions?