David Golembiowski
David Golembiowski

Reputation: 175

Why does this lifetime not "expire"?

For the following block, when do the lifetimes 'b and 'c end?

use core::ops::Deref;

#[derive(Debug)]
struct A<'b, 'c, T> {
    child_b: &'b T,
    child_c: &'c T
}

impl<'b, 'c, T> A<'b, 'c, T> {
    pub fn new_wrapper(b_value: &'b T, c_value: &'c T) -> A<'b, 'c, T> {
        A {
            child_b: b_value,
            child_c: c_value
        }
    }
}

fn doesnt_drop_borrow<T: Copy>(ty: &T) {
    *ty;
}

fn drop<T>(ty: T) { }

fn main() {
    let b: String = "wonderful".into();
    let c: String = "lifetime".into();
    let a = A::new_wrapper(&b, &c);
    println!("hello this {:?} world", &a);
    doesnt_drop_borrow(&a.child_c);
    drop(a.child_c);
    println!("hello this {:?} world", &a);
}

Upvotes: 3

Views: 132

Answers (1)

prog-fh
prog-fh

Reputation: 16785

Since a.child_c has the type &String, the ty parameter in doesnt_drop_borrow(&a.child_c) has type &&String, and *ty has type &String so the original String (c) won't be dropped.

I don't know what precisely motivates your question but I guess it's the fact that you can still use a after calling drop(a.child_c). The name of this function is misleading because the ty parameter here has type &String (the same as a.child_c). So the ty parameter appears as a new immutable borrow of the original c, then is immediately dropped, but the original c is not dropped. When a reference is dropped the referred to value is not.

None of these two functions actually move the original String, they only deal with references.

So b and c here live till the end of main(), and so does a which contains references to them.

Upvotes: 4

Related Questions