Reputation: 105
I have the following code:
#[derive(Debug)]
pub enum List<'a> {
Nil,
Cons(i32, &'a List<'a>)
}
{
let x = Cons(1, &Cons(2, &Nil));
println!("{:?}", x);
}
It works fine. I don't understand why this code doesn't report any error, isn't the Cons(2, &Nil)
dropped before constructing Cons(1, _)
?
Moreover, after I added an empty impl Drop
for List
, the above code doesn't work any more:
impl<'a> Drop for List<'a> {
fn drop(&mut self) {
}
}
It reports errors that borrowed value does not live long enough
for Cons(2, _)
and Nil
.
Why is there such difference between before and after adding impl Drop
?
Upvotes: 4
Views: 284
Reputation: 322
Isn't the
Cons(2, &Nil)
dropped before constructingCons(1, _)
?
If you bind a reference to a temporary, Rust extends the lifetime of the temporary as needed for the binding; see this answer for details.
Why is there such difference between before and after adding
impl Drop
?
See this comment. The extended lifetime of the temporary matches the lifetime of x
in your example. When a struct
containing references has no Drop
implementation,
it’s permissible for reference and referent to have identical lifetimes: the reference can’t be used unsafely. Introducing a
Drop
impl to the situation requires the referent to strictly outlive the reference, to ensure there is a clear order in which to rundrop
methods.
Upvotes: 3