Beginner lifetime question


#1

This simple code is not compiling. What seems to be the issue?

main.rs:10:5: 10:15 error: the parameter type `T` may not live long enough [E0309]
main.rs:10     val: &'a T,
               ^~~~~~~~~~
main.rs:10:5: 10:15 help: run `rustc --explain E0309` to see a detailed explanation
main.rs:10:5: 10:15 help: consider adding an explicit lifetime bound `T: 'a`...
main.rs:10:5: 10:15 note: ...so that the reference type `&'a T` does not outlive the data it points at
main.rs:10     val: &'a T,
               ^~~~~~~~~~
error: aborting due to previous error



use std::collections;

fn main() {
    let mut demo: MyCollection<Data<i32>> = MyCollection::new(4);
    demo.add(Data::new(2));
    println!("MyCollection is {:?}", demo);
}

struct Data<'a, T> {
    val: &'a T,
}

impl<'a, T> Data<'a, T>{
    pub fn new(value: &'a T) -> Data<'a, T> {
        Data { val: value }
    }
}
#[derive(Debug)]
struct MyCollection<T> {
    value: Vec<T>,
}

impl<T> MyCollection<T>{
    pub fn new(capacity: usize) -> Self {
        MyCollection { value: Vec::with_capacity(capacity) }
    }

    pub fn add(&mut self, val: T) {
        self.value.push(val);
    }
}

#2

“consider adding an explicit lifetime bound T: 'a…”. See https://doc.rust-lang.org/error-index.html#E0309, https://doc.rust-lang.org/nightly/book/traits.html#trait-bounds-on-generic-structs etc.

Any suggestions to improve the error message or the documentation would be appreciated.


#3

I modified it but still have compilation error.

main.rs:6:38: 6:39 error: x does not live long enough
main.rs:6 let data: Data = Data::new(&x);

use std::collections;

fn main() {
    let mut demo: MyCollection<Data<i32>> = MyCollection::new(4);
    let x: i32 = 20;
    let data: Data<i32> = Data::new(&x);
    demo.add(data);
    println!("MyCollection is {:?}", demo);
}

#[derive(Debug)]
struct Data<'a, T: 'a> {
    val: &'a T,
}

impl<'a, T> Data<'a, T>{
    pub fn new(value: &'a T) -> Data<'a, T> {
        Data { val: value }
    }
}

#[derive(Debug)]
struct MyCollection<T> {
    value: Vec<T>,
}

impl<T> MyCollection<T>{
    pub fn new(capacity: usize) -> Self {
        MyCollection { value: Vec::with_capacity(capacity) }
    }

    pub fn add(&mut self, val: T) {
        self.value.push(val);
    }
}

#4
let x: i32 = 20;
let mut demo: MyCollection<Data<i32>> = MyCollection::new(4);
let data: Data<i32> = Data::new(&x);
demo.add(data);

‘x’ should live longer than ‘demo’


#5

Yes. But how do I make it live longer?


#6

In your example, x is initialised below demo. Initialise x first and later initialise demo. This way x will be the last one to get destroyed.


#7

Awesome! Thanks @kteza1.