Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do generic lifetimes not conform to the smaller lifetime of a nested scope?

According to The Rust Programming Language:

Since scopes always nest, another way to say this is that the generic lifetime 'a will get the concrete lifetime equal to the smaller of the lifetimes of x and y.

fn main() {
    let x = "abcd";
    let result;
    {
        let y = "qwerty";
        result = longest(x, y);
    }
    println!("The longest string is {}  ", result);

}

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

In the main function, "the smaller of the lifetimes of x and y" is the nested scope. This should be the lifetime of the value in result as well, but the result contains the correct value from outside of that nested scope.

Why does this code work correctly?

like image 786
saga Avatar asked Mar 15 '18 05:03

saga


1 Answers

That's only true when talking about lifetimes derived from borrowing local variables. In this case, the relevant lifetime is the lifetime of the string data, which for string literals is 'static. In other words, the &strs are pointing to data stored elsewhere (in the static data segment, specifically), so they don't interact with stack lifetimes at all.

If we change the example slightly, we can induce the behaviour you're expecting:

fn main() {
    let x = "abcd";
    let result;
    {
        let y = "qwerty";
        result = longest(&x, &y);
    }
    println!("The longest string is {}  ", result);

}

fn longest<'a>(x: &'a &'static str, y: &'a &'static str) -> &'a &'static str {
    if x.len() > y.len() {
        x
    } else {
        y
    }
}

Which fails to compile with:

error[E0597]: `y` does not live long enough
  --> src/main.rs:6:35
   |
6  |             result = longest(&x, &y);
   |                                   ^ borrowed value does not live long enough
7  |         }
   |         - `y` dropped here while still borrowed
...
10 |     }
   |     - borrowed value needs to live until here

This fails because now we're talking about borrows into the stack.

like image 150
DK. Avatar answered Sep 19 '22 13:09

DK.