Where in Rust's specification does it say that if the returned reference of a function has the same lifetime as one of the reference arguments, then the returned reference is considered a borrow of that argument?
Example:
struct T {
i: i32
}
struct U {
i: i32
}
static GLOBAL: U = U { i: 0 };
fn foo<'t, 'u>(t: &'t mut T, u: &'u mut U) -> &'u U {
&GLOBAL
}
fn main() {
let mut t = T { i: 0 };
let mut u = U { i: 0 };
let ref_u = foo(&mut t, &mut u);
let ref_u_2 = &u;
// println!("{}", ref_u.i);
}
(Playground)
If I uncomment the println!
, the compilation will fail with the message:
error[E0502]: cannot borrow `u` as immutable because it is also borrowed as mutable
--> src/main.rs:15:19
|
14 | let ref_u = foo(&mut t, &mut u);
| ------ mutable borrow occurs here
15 | let ref_u_2 = &u;
| ^^ immutable borrow occurs here
16 | println!("{}", ref_u.i);
| ------- mutable borrow later used here
I think the reason why I have to use println!
at the end to make the compilation fail is because of non-lexical lifetimes. I need to use ref_u
so that its lifetime doesn't end immediately. I used two arguments to show that the t
argument is unaffected, but this example also works with only one argument.
Note that the returned reference has the 'static
lifetime. To me, this implies the following two points:
u
argument.&'t U
, then the program compiles.This seems reasonable, but I couldn't find any explicit reference to this rule in the Rust Reference or the Rust Book. Is this behavior implied somewhere?
Also, I find it interesting that the error message considers ref_u
a mutable borrow, even though it isn't a mutable reference.
This is in the book under Lifetime Annotations in Function Signatures:
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str { […]
function definition specifying that all the references in the signature must have the same lifetime
'a
So no I would not say the return value borrows from the parameter, instead I'd say it has the same lifetime. It certainly can borrow from the parameter, but it does not have to. That means as long as the return value is considered live, the parameter is also considered live.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With