Type coercion from trait object

When types are erased, the common behavior is either described within a trait or it is lost.

So the get_data needs to be added as a trait bound for the trait used in the trait object:

#[deny(bare_trait_objects)]

trait Foo {
    type Data;

    fn get_data (&'_ self) -> Option<&'_ Self::Data>;
}

trait Bar : Foo {} // you can use your own `Foo` trait as a supertrait

// type TraitObject = dyn Bar; // error, needs to specify Data

The issue is that you have an associated type Data. This type needs to be the same for all trait objects.

Two solutions:

  • specify that your trait object is constrained to a specific Data associated type:

    type TraitObject = dyn Bar<Data = Vec<u8>>; // OK
    
  • use another trait object (or an enum, see this thread)

    #[deny(bare_trait_objects)]
    
    use ::std::fmt::Display;
    
    trait Foo {
        fn get_data (&'_ self) -> Option<&'_ dyn Display>;
    }
    
    trait Bar : Foo {} // you can use your own `Foo` trait as a supertrait
    
    type TraitObject = dyn Bar;
    
    fn foo (x: &'_ TraitObject)
    {
        println!("{}", x.get_data().unwrap());
    }