Hi all,
I'm trying to build something similar to Cursor for Trees, where I traverse a mutable tree and build a stack of the nodes in the path as I perform a DFS. The difference is that my tree is heterogenous: nodes are of different types but they share a common trait. The nodes also take a type parameter S
. Unfortunately, trying to implement the linked solution gives me a compiler error (detailed below). Primarily, I'd like to know what's causing the compiler error and how to fix it and, secondarily, alternative solutions to the problem.
The following code is the minimal code I could find that created the error while still retaining the heterogenous feature of my tree.
Here's a minimal example of what I'm working with:
trait Node<S> {
fn get_val(&self) -> &S;
}
struct NodeA<S> {
val: S,
a: Option<Box<NodeA<S>>>,
b: Option<Box<NodeB<S>>>,
}
struct NodeB<S> {
val: S,
b: Option<Box<NodeB<S>>>,
}
impl<S> Node<S> for NodeA<S> {
fn get_val(&self) -> &S {
&self.val
}
}
impl<S> Node<S> for NodeB<S> {
fn get_val(&self) -> &S {
&self.val
}
}
Here's the traversal implementation based upon Cursor for Trees, since the tree is heterogenous, I used the common trait for the raw pointer:
struct TraverseMut<S> {
stack: Vec<*mut dyn Node<S>>,
}
impl<S> TraverseMut<S> {
fn map_a(&mut self, na: &mut NodeA<S>) {
self.stack.push(na as *mut dyn Node<S>);
// Do stuff to mutate node
if let Some(ca) = &mut na.a {
self.map_a(ca.as_mut());
}
if let Some(ba) = &mut na.b {
self.map_b(ba.as_mut());
}
self.stack.pop();
}
fn map_b(&mut self, na: &mut NodeB<S>) {
self.stack.push(na as *mut dyn Node<S>);
// do stuff to mutate node
if let Some(ba) = &mut na.b {
self.map_b(ba.as_mut());
}
self.stack.pop();
}
}
However, this gives me the compiler error:
error[E0310]: the parameter type `S` may not live long enough
--> src/main.rs:38:25
|
36 | impl<S> Traverse<S> {
| - help: consider adding an explicit lifetime bound...: `S: 'static`
37 | fn visit_a(&mut self, na: &NodeA<S>) {
38 | self.stack.push(na as *const dyn Node<S>);
| ^^ ...so that the type `NodeA<S>` will meet its required lifetime bounds
I'm not sure why S
needs a lifetime for a trait object or how to fix it as it's unclear to me where the lifetime specifier would go.