This may be a XY problem question, so please bear with me.
I have a trait (DoProducer) whose function returns trait objects implementing another trait (Do).
I would like an implementer to be able to return a subtrait of Do (DoMore). The compiler complains about the function signatures not matching.
I don't strictly need this to be a subtrait. Rather I want to be able to say "this implementation of DoProducer returns something that promises to implement Do and DoMore". How do I express this?
This is a playground for a "non-subtrait" implementation, which runs into the error of not being able to add non-auto traits. Rust Playground
Alternatively, is there some other way to achieve a similar result?
You can do this by returning an associated type, which lets each implementation of the trait specify its own return type: (Playground)
trait DoProducer {
type Result: Do + ?Sized;
fn produce(&self) -> Box<Self::Result>;
}
struct DoProducerImpl {}
impl DoProducer for DoProducerImpl {
type Result = dyn DoMore;
fn produce(&self) -> Box<Self::Result> { // <---- I want to be able to do this
if false {
Box::new(A {})
} else {
Box::new(B {})
}
}
}
For the non-subtrait version, you’ll need to define a trait that’s a subtrait of both, because the dyn Trait system can only add additional traits if they’re markers with no methods:
trait DoAndMore: Do + DoMore {}
impl<T: Do + DoMore> DoAndMore for T {}