I have two functions doing the same thing, but only one compiles without error:
struct Something<'number> {
numbers: &'number [i64]
}
impl<'number> Something<'number> {
fn hasna() {
let dummy = [0, 1, 2, 3];
let s = Self {numbers: &dummy[1..3]};
}
fn bruzzn() {
let dummy = [0, 1, 2, 3];
let s = Something {numbers: &dummy[1..3]};
}
}
fn bruzzn does compile, but hasna doesn't - with the error
77 | impl<'number> Something<'number> {
| ------- lifetime `'number` defined here
78 | fn hasna() {
79 | let dummy = [0, 1, 2, 3];
| ----- binding `dummy` declared here
80 | let s = Self {numbers: &dummy[1..3]};
| -^^^^^------
| ||
| |borrowed value does not live long enough
| this usage requires that `dummy` is borrowed for `'number`
81 | }
| - `dummy` dropped here while still borrowed
Why is using Self a problem when using the struct name works?
First, a local variable necessarily does not outlive a lifetime that is a parameter to the function. In this case: it is always impossible to create an &'number [i64] that points to dummy.
Second, Self is an alias for exactly the type given in the impl. In this case, Self is an alias for Something<'number>. So, if we replace Self with Something<'number>, and notice the lifetime in the other function, we get:
fn hasna() {
let dummy = [0, 1, 2, 3];
let s = Something<'number> {numbers: &dummy[1..3]};
}
fn bruzzn() {
let dummy = [0, 1, 2, 3];
let s = Something::<'_> {numbers: &dummy[1..3]};
}
bruzzn compiles because it creates a Something<'1>, where '1 is the unnamed lifetime of a borrow of the local variable dummy, which contains a reference &'1 [i64].
hasna does not compile because it is trying to create a Something<'number>, which must contain a reference &'number [i64], which cannot be obtained by borrowing the local variable dummy.
bruzzn has a lifetime parameter number — its full name is Something::<'number>::bruzzn — but it does not actually make any use of that lifetime parameter, because it never mentions it in any way, not even via Self.
I think almost everybody’s mental model of lifetimes is not really complete. There’s a lot of subtleties (mostly to do with local variables, not named lifetimes).