static mut GLOBAL_VARS : u32 = 100;
struct X (u32);
impl X {
// lifetime parameters are all specified for later work
fn borrow_from_self<'h>(&'h mut self) -> &'h mut u32 {
&mut self.0
}
fn borrow_from_input<'i, 'j>(&'i mut self, _in: &'j mut u32) -> &'j mut u32 {
_in
}
//fn borrow_from_global<'k>(&'k mut self) -> &'static mut u32
fn borrow_from_global<'k>(&'k mut self) -> &'k mut u32 {
unsafe { &mut GLOBAL_VARS }
}
}
fn main() {
let mut v1 = X(10);
let mut v2 = 20;
let v3 = v1.borrow_from_input(&mut v2);
v1.borrow_from_self();
let v4 = v1.borrow_from_self();
let v5 = v1.borrow_from_global();
}
I have read Lifetimes - The Rustonomicon and did some tests. But I'm still a little confused about how rust knows lifetimes.
In the nomicon document, it shows situations only with one lifetime parameter. And I want to know how rust processes it when multiple lifetime parameters given.
I mainly have 3 questions:
- v3 do not conflict with v4. Why?
- v5 returns a global variables. But it conflicts with v4. Why? (It works when fn signature replaced with the one commented)
- I borrow_from_self'ed twice. But no conflicts. Why?
Let me expand the fn main (with my dumb mind) according to nomicon docs :
fn main() {
'a: {
let v1 = X(10);
'b: {
let v2 = 20;
'c: {
let v3 = X::borrow_from_input::<'?,'?>(&'? mut v1, &'? mut v2);
{
X::borrow_from_self::<'c>(&'c mut v1);
}
'd: {
let v4 = X::borrow_from_self::<'d>(&'d mut v1);
'e: {
let v5 = X::borrow_from_global::<'e>(&'e mut v1);
}
}
}
}
}
}
Firstly, correct me if anything is wrong.
Secondly, am I put the line without "let" correctly? If yes, question 3 is answered. And is any non-"let" lines are such analyzed(every statement/expression running in an temporary scope)?
Thirdly, can anyone fill all '?' above? AFAIK from docs, '?' should be one of 'c', 'd', 'e'. But I just don't know what to fill.
Lastly, I'd much appreciate anyone could explain the details how rust understands these.