amlo
amlo

Reputation: 105

Rust reference to temporary value doesn't report error

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

Answers (1)

Daniel S.
Daniel S.

Reputation: 322

Isn't the Cons(2, &Nil) dropped before constructing Cons(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 run drop methods.

Upvotes: 3

Related Questions