I have a trait in which I want to provide a method. This method should be implemented in terms of some assistants who do not have a business inside the line and are sufficiently nontrivial that dynamic polymorphism makes more sense than their general nature. So I have the code in the lines
fn use_trait(x: &Trait) { println!("object says {}", x.needed()); } trait Trait { fn needed(&self) -> &str; fn provided(&self) { use_trait(self); } } struct Struct(); impl Trait for Struct { fn needed(&self) -> &str { "Hello, world!" } } fn main() { Struct().provided(); }
Which, however, does not compile , with an error:
error[E0277]: the trait bound `Self: std::marker::Sized` is not satisfied --> <anon>:9:19 | 9 | use_trait(self); | ^^^^ the trait `std::marker::Sized` is not implemented for `Self` | = help: consider adding a `where Self: std::marker::Sized` bound = note: required for the cast to the object type `Trait`
I understand why - it is not guaranteed that someone does not implement the attribute for a non-standard type (conversion from &T where T: Trait
to &Trait
requires T: Sized
, but the declaration does not require this).
However, the advice will not do what I need. I can add
fn needed(&self) -> &str where Self: Sized
but then the needed()
method will not be available on &Trait
(because Trait : ?Sized
), which makes the thing useless, because the type (the actual one that does something useful) is always treated as Arc<Trait>
. By adding
trait Trait: Sized
even worse, because it does not allow &Trait
( Trait
, because the type is not supported, therefore the Trait
type does not implement the Trait
attribute).
Of course I can just do
fn use_trait<T: Trait>(x: &T)
but in real code there is a lot behind it, so I donโt want monomorphization there, especially because the trait is always treated as an object-object.
Is it possible to tell Rust that all types that impl Trait
should be sorted, and here is the definition of a method that should work for all of them?