So trait objects can't have methods with generics - that looks fine. But in this language the only ways to use abstraction mechanism are available through generics and trait objects. Which means that for each trait I have to decide beforehand if it can be used as an object at all and use dyn in there everywhere instead of impl. And all taken traits inside it must be made same way to support this. This feel very ugly. Can you suggest anything or tell me why it's designed this way?
fn main() {}
// some abstracted thing
trait Required {
fn f(&mut self, simple: i32);
}
// this trait doesn't know that it's going to be used by DynTrait
// it just takes Required as an argument
// nothing special
trait UsedByDyn {
// this generic method doesn't allow this trait to be dyn itself
// no dyn here: we don't know about DynTrait in this scope
fn f(&mut self, another: impl Required);
}
// this trait needs to use UsedByDyn as a function argument
trait DynTrait {
// since UsedByDyn uses generic methods it can't be dyn itself
// the trait `UsedByDyn` cannot be made into an object
//fn f(&mut self, used: Box<dyn UsedByDyn>);
// we can't use UsedByDyn without dyn either otherwise Holder can't use us as dyn
// the trait `DynTrait` cannot be made into an object
// fn f(&mut self, used: impl UsedByDyn);
// how to use UsedByDyn here?
}
struct Holder {
CanBeDyn: Box<dyn DynTrait>,
}