Vec with generics and lifetime

Hi!
Somewhat new to rust. I've tried looking around but can't find any similar problems, potentially due to incompetence or lack of terminology, so sorry if I'm repeating the question.

Problem:
I want to create a Graph, where the nodes implement a trait. Thus I modelled the Graph struct as follows (note: this gives a compilation error, I'll get to it later)

pub struct Graph<'t, T: Node> {
    nodes: Vec<T>,
}

I also want to be able to generate the Nodes on instantiation of the Graph, thus the Node trait to implements a new function as follows: (See Appendix 2 for a Node struct: NodeDef)

pub trait Node {

    fn new(n_nodes: usize, index:usize) -> Self;

    //.... Other functions
}

To be able to test my Graph I implement a randomize function (see Appendix 1 for implementation). This function creates the Vec "nodes" in the Graph struct.

Thus, the problem:
The Graph struct gives me the error
"parameter 't is never used"

Setting the lifetime of T gives me the error:
"expected trait, found type parameter T not a trait"

    nodes: Vec<T + 't>

I could change the T to a reference to a Generic, see below. But I'd very much prefer keeping it as a Generic for perf. reasons.

    nodes: Vec<&'t T>

And setting the Vec to a reference and using the lifetime there makes me unable to generate it in the generate_graph function (see Appendix 1)

    nodes: &'t Vec<T>

I'm very thankful for any help
/Simon

Appendix 1

Graph function implementation, including the initialization

impl<'t, T> Graph<'t, T> where T:Node {

    pub fn randomize(seed: Option<u64>) -> Graph<'t, T> {
        let mut graph = Graph::generate_graph(seed);
        graph.init_neigh_hops();
        return graph;
    }

    //.... Other functions

    fn generate_graph(seed: Option<u64>) -> Graph<'t, T> {

        //..Other stuff

        //Init nodes
        let n_nodes = 10;
        let mut nodes:Vec<T> = Vec::with_capacity(n_nodes);
        
        for i in 0..n_nodes {
            nodes.push(&Node::new(n_nodes, i));
        }
        //..Other stuff

        let g = Graph { nodes: nodes };

        return g;
    }

}

Appendix 2

NodeDef is implementation

pub struct NodeDef {
    neighbours: Vec<usize>,
    pos: Pos,
    neigh_hops: Vec<usize>,
    index: usize,
}

impl Node for NodeDef {

    fn new(n_nodes: usize, index:usize) -> Self {
        return NodeDef{neighbours: Vec::new(), pos: Pos::default(), neigh_hops: vec![0; n_nodes], index};
    }

    //.... Other functions
}

The error message is telling you that the 't parameter is unnecessary because you're not using it anywhere. So just delete it:

pub struct Graph<T: Node> {
    nodes: Vec<T>,
}
2 Likes

You're right!
Though it gave me an error with lifetimes on the T Generic for another function.

But reading through the error more thoroughly (and the tip from the Rust compiler) it was easily solvable.
Thank you so much for the help!

I'll add my error and solution below for anyone in a similar situation

New Error

Code:

pub fn display<T: Node>(graph: Graph<T>) {
   //.... Other code

    let wh = MyWindowHandler::new(graph, win_size);
    window.run_loop(wh);
}

Error:
the parameter type T may not live long enough ...so that the type T will meet its required lifetime boundsrustcE0310
graphics.rs(209, 23): consider adding an explicit lifetime bound...: + 'static

Solution

pub fn display<T: Node + 'static>(graph: Graph<T>) {
   //.... Other code

    let wh = MyWindowHandler::new(graph, win_size);
    window.run_loop(wh);
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.