So far I have rarely had issues with Rust's type inference, but I fear I don't quite understand the problem with the following code:
trait SpecificTrait {}
struct SpecificStruct;
impl SpecificTrait for SpecificStruct {}
trait GeneralTrait {}
impl<T: SpecificTrait> GeneralTrait for T {}
fn new_specific_box() -> Box<dyn SpecificTrait> {
Box::new(SpecificStruct {})
}
fn new_general_box(from_specific_box: bool) -> Box<dyn GeneralTrait> {
if from_specific_box {
new_specific_box()
} else {
Box::new(SpecificStruct {})
}
}
I assume it has to do with Rust probably still not supporting upcasting, though in this code SpecificTrait
does not require GeneralTrait
, but rather implements the more general trait generically over all types that implement SpecificTrait
.
I am aware that the trait object types are different (which leads to the error in the above code), but I would expect type inference to acknowledge that every dyn SpecificTrait
object should also be expressable as a dyn GeneralTrait
object. However, I also cannot simply cast a Box<dyn SpecificTrait> as Box<dyn GeneralTrait>
, either.
So, how would I (idomatically) have to go about re-expressing my Box<dyn SpecificTrait>
as a Box<dyn GeneralTrait>
?
Another answer explained why you can't simply cast the trait object to get the result you want. However, there is a workaround:
impl SpecificTrait for Box<dyn SpecificTrait>{}
fn new_general_box(from_specific_box: bool) -> Box<dyn GeneralTrait> {
if from_specific_box {
Box::new(new_specific_box())
} else {
Box::new(SpecificStruct {})
}
}
In words, simply implement your specific trait for a boxed trait object, then box that. Not the most efficient, but it will work.