I would like to construct a parse tree of different node types that share functionality via a trait. I need different types because different kinds of nodes might have slightly different types of fields. For example, a branch node like a paragraph does not hold text directly; only via its child Text nodes does it have access to its concrete contents.
With this in mind, I've made the following specifications:
use std::cell::RefCell;
use std::rc::{Rc, Weak};
/// ### Parent
/// A shorthand for an optional (parent might not exist)
/// weak reference to a parent node.
type Parent<T> = Option<Weak<RefCell<T>>>;
/// ### Children
/// Shorthand for a vector of owned child nodes.
/// Empty vector indicates no children.
/// Leaf nodes will assert this.
type Children<T> = Vec<Rc<RefCell<T>>>;
/// ### Document
/// Document root node
pub struct Document<T: Node> {
    id: usize,
    id_counter: NodeId,
    parent: Parent<T>,
    children: Children<T>,
    // -- snip --
}
/// ### trait Node
/// A trait defining functionality for general document tree nodes.
pub trait Node {
    type ID;
    type Parent;
    type Children;
    fn new() -> Self;
}
impl<T: Node> Node for Document<T> {
    type ID = usize;
    type Parent = Parent<T>;
    type Children = Children<T>;
    fn new() -> Self {
        let mut id_counter = NodeId::new();
        Document {
            id: id_counter.assign(),
            id_counter: id_counter,
            parent: None,
            children: Vec::new(),
            // -- snip --
        }
    }
}
/// ### NodeId
/// A global counter of document nodes
#[derive(Debug)]
pub struct NodeId {
    id: usize,
}
impl NodeId {
    /// ### new
    /// A NodeId constructor. In the beginning,
    /// there are 0 Nodes.
    pub fn new() -> Self {
        NodeId { id: 0 }
    }
    /// ### increment
    /// Increments the `NodeId` counter by 1.
    pub fn increment(&mut self) {
        self.id += 1;
    }
    /// ### get
    /// Return a copy of the NodeId counter.NodeId
    pub fn assign(&mut self) -> usize {
        let current = self.id;
        self.increment();
        current
    }
}
However, Rust will not let me construct a new empty document tree in a test. The code
#[test]
fn new_document_node() {
    let doc = Document::new();
    assert_eq!(0, doc.id);
}
results in the error
error[E0282]: type annotations needed for `Document<T>`
  --> src/lib.rs:85:15
   |
85 |     let doc = Document::new();
   |         ---   ^^^^^^^^^^^^^ cannot infer type for type parameter `T`
   |         |
   |         consider giving `doc` the explicit type `Document<T>`, where the type parameter `T` is specified
Adding a type annotation does not help:
let doc: Document<T: Node> = Document::new();
results in
error[E0658]: associated type bounds are unstable
  --> src/lib.rs:85:23
   |
85 |     let doc: Document<T: Node> = Document::new();
   |                       ^^^^^^^
   |
   = note: see issue #52662 <https://github.com/rust-lang/rust/issues/52662> for more information
   ^^^^^^^^^^^^^^^^^^^^^
error[E0107]: wrong number of type arguments: expected 1, found 0
  --> src/lib.rs:85:14
   |
85 |     let doc: Document<T: Node> = Document::new();
   |              ^^^^^^^^^^^^^^^^^ expected 1 type argument
error[E0229]: associated type bindings are not allowed here
  --> src/lib.rs:85:23
   |
85 |     let doc: Document<T: Node> = Document::new();
   |                       ^^^^^^^ associated type not allowed here
Is it possible to create a tree of objects that implement common functionality, maybe slightly differently? For example, my leaf node types have no children, so their get_children() -> Option<Vec<Children>> method would return an empty vector.
Is this at all achievable at least somewhat ergonomically in Rust?
 
    