I have a tree structure of nodes, where I want each node to be able to send and receive messages to/from other nodes. I have an issue with storing the children of each node, though:
pub trait Node
{
type MessageType;
}
pub struct NodeWrapper<MessageType>
{
id : NodeId,
name : Option<String>,
children : Vec<NodeWrapper<Any>>,
node : Box<Node<MessageType=MessageType>>,
}
This complains that NodeWrapper<Any> isn't Sized, which it needs to be store in a Vec I guess. However, logically, the generic parameter doesn't make this not-sized, as it just represents the associated type. The trait object's size is known at compile-time. Is this a limitation of the type-system, can I work around this, or am I just being dim?
You are correct, NodeWrapper<Any> is sized. But the error message I see does not say that NodeWrapper<Any> is unsized, it says that Any is unsized; which indeed is true.
Compiling playground v0.0.1 (file:///playground)
error[E0277]: the trait bound `std::any::Any + 'static: std::marker::Sized` is not satisfied
--> src/main.rs:13:5
|
13 | children : Vec<NodeWrapper<Any>>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::any::Any + 'static` does not have a constant size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `std::any::Any + 'static`
note: required by `NodeWrapper`
--> src/main.rs:9:1
|
9 | pub struct NodeWrapper<MessageType>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The error message notably points to two things:
the children field
the definition of NodeWrapper
And yes, these two things do conflict. Generic type parameters always come with an implicit Sized bound, meaning that your definition of NodeWrapper is equivalent to: