The following code won't compile due to two instances of this error:
error[E0277]: the trait bound
Self: std::marker::Sized
is not satisfied
I don't understand why Sized
is required in this instance as both &self
and &Any
are pointers and the operation does not require knowledge of the size of the structure that implements the trait, it only requires knowledge of the pointer itself and the type it is converting from and to, which it will have because &self
is generic when implemented inside a trait.
I think this may be an instance of the compiler enforcing unnecessary constraints and I've considered filing an issue with the rust-lang GitHub repo but I figured I should probably see if someone here knows something I don't before I go file an issue.
use std::any::Any;
trait Component: Any {
fn as_any(&self) -> &Any {
self
}
fn as_any_mut(&mut self) -> &mut Any {
self
}
}
The alternative to this is to make as_any()
and as_any_mut()
required functions for the structs that implement this trait, but for those structures the implementation would always be exactly as displayed here down to each individual character, resulting in several instances of identical boilerplate code.
I found what I consider to be a great solution that didn't require new compiler features.
pub trait Component {
// ...
}
pub trait ComponentAny: Component + Any {
fn as_any(&self) -> &Any;
fn as_any_mut(&mut self) -> &mut Any;
}
impl<T> ComponentAny for T
where T: Component + Any
{
fn as_any(&self) -> &Any {
self
}
fn as_any_mut(&mut self) -> &mut Any {
self
}
}
From here, I just change all my APIs to accept ComponentAny
instead of Component
. Because Any
is automatically implemented for any 'static
type, ComponentAny
is now automatically implemented for any 'static
type that implements Component
. Thanks to Is there a way to combine multiple traits in order to define a new trait? for the idea.