#[derive(Debug)]
struct Struct;
fn main() {
let s = Struct;
let mut v = Vec::new();
v.push(&s);
drop(s); // Error: cannot move out of `s` while `s` is borrowed
println!("{:?}", v);
}
The compiler complains that drop(s) is illegal here because it attempts to move the value out of s while it is still borrowed. But how does the compiler know that the borrow of s lives a long as v and is therefore must still be valid when println!("{:?}", v); is called? What is it about the signature of Vec::push(&mut self, value: T) that tells the borrow checker that all pointees of reference-typed values must live at least as long as this Vec does?
Hm.. So are you saying that If a value's concrete type contains any lifetime parameters (including elided anonymous lifetime parameters), the value can only live as long as the shortest such lifetime parameter specifies?
Note that saying that a lifetime parameter is “elided anonymous” is just saying things about the input syntax. The borrow checker does not care how you write, or don't write, a lifetime parameter, only how it relates to other lifetimes. Elision does not cause lifetime parameters to not exist.
There is an exception to this rule, which is currently an unstable feature but is made use of by some standard library types such as Vec. Specifically, it is possible for some types, such as Vec, to be dropped at end of scope even when they contain already-expired references, even though this technically involves calling the Drop::drop() function on a type containing expired references, because Vec’s drop doesn't actually access any of its elements. This exception is called #[may_dangle] or the “dropck eyepatch”.
I mention this only for completeness — it does not affect your example program, because you’re trying to read v, not just drop it.