Here is an offending example:
// Some traits
trait Behaviour {
type Sub: SubBehaviour;
}
trait SubBehaviour {}
// Some implementations of these traits
s
So the answer to your first question is covered by Tim's answer and is correct, you might not want your Example to be generic. In that case, you need to use some sort of type erasure:
// Some traits
trait Behaviour {
type Sub: SubBehaviour;
}
trait SubBehaviour {}
// Some implementations of these traits
struct A;
impl Behaviour for A {
type Sub = B;
}
struct B;
impl SubBehaviour for B {}
struct AnyBehaviour {
closure: Box,
}
impl AnyBehaviour {
fn new>(b: &T) -> Self {
let closure = || {
//let sub = T::Sub::new();
println!("Can use T here");
};
AnyBehaviour {
closure: Box::new(closure),
}
}
}
// Struct that holds a collection of these traits.
struct Example {
behaviours: Vec,
}
impl Example {
fn add_behaviour>(&mut self, b: &T) {
self.behaviours.push(AnyBehaviour::new(b));
}
}
fn main() {
let b = A;
let mut e = Example {
behaviours: Vec::new(),
};
e.add_behaviour(&b);
}
Within the closure, you have access to all the types needed call the traits functions with whatever subtype needed.
Why this happens, is mostly because you actually need a definition of the associated type in order for the trait to be "complete" so the compiler can work with it. Tim's answer answers that by the definition to be higher up in the chain (outside of Example) instead of inside.