I've run into a situation where the compiler seems to be applying a lifetime elision rule that isn't described in the documentation. Here is a minimal program to demonstrate:
struct Container<T> {
value: T
}
impl<T> Container<T> {
fn explicit_param_type(&mut self, v: &str) {
}
fn generic_param_type(&mut self, v: T) {
}
}
fn main() {
let mut h: Container<&str> = Container{value: "foo"};
{
let s = String::from("Hello World");
h.explicit_param_type(&s[..]); // compiler allows this
h.generic_param_type(&s[..]); // compiler complains about this
}
println!("{}", h.value)
}
The compiler is ok with the call to the explicit_param_type
, but complains about the call to generic_param_type
with the error:
error[E0597]: `s` does not live long enough
--> src/main.rs:19:31
|
19 | h.generic_param_type(&s[..]);
| ^ borrowed value does not live long enough
20 | }
| - `s` dropped here while still borrowed
21 |
22 | println!("{}", h.value)
| ------- borrow later used here
The only difference between the two methods is that explicit_param_type
has a parameter of type &str, but generic_param_type
has a parameter of type T, which in this case resolves to &str.
Based on reading the lifetime elision rules in The Rust Programming Language and The Rust Reference, I would have thought that for both methods, the self
and v
parameters would get their own distinct lifetime parameter. That seems to be the case for explicit_param_type()
, but for generic_param_type()
, it seems like the compiler instead infers the same lifetime for self
and v
, and therefore complains because the method argument has a shorter lifetime than self. I can't find anything in the documentation that would explain why the compiler would do this. From my reading of the docs, both method calls in the sample program should compile.
Is there somewhere in the docs that explain why the compiler infers different lifetimes for a method parameter when its type is generic?
Thanks.