I'm still struggling with this little example
This passes without the need for lifetime specifiers
fn myfn(x: &i32) -> &i32 {
x
}
Changing the argument type from &i32 to i32 causes the compiler to complain:
this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments, consider giving it an explicit bounded or 'static lifetime
Is this determined by a set of more fundamental rules? Or did somebody just figure out that fn(x: &T) -> &T just never needs lifetime specifiers but fn(x: T) -> &T does and those patterns are hardcoded into the checker?
From the Orielly programming rust book:
When a function takes a single reference as an argument, and returns a single reference, Rust assumes that the two must have the same lifetime.
From The Rust Programming Language:
When returning a reference from a function, the lifetime parameter for the return type needs to match the lifetime parameter for one of the parameters. If the reference returned does not refer to one of the parameters, it must refer to a value created within this function, which would be a dangling reference because the value will go out of scope at the end of the function.
I take that quotes to mean that in that situation the input and output are always related, but that is not necessarily true, the following passes too:
fn myfn(_: &i32) -> &i32 {
&1
}
Related question:
If these are just function signatures patterns the borrow checker is looking for, how many more are there?