2

I have a function that returns a reference to a trait (trait_ref()) and another function that takes a reference to a generic trait implementation (take_trait_ref_generic).

However, it's not possible to pass the reference I get from the first function to the second one. Rustc complains that "the trait std::marker::Sized is not implemented for SomeTrait".

Even though that's true, why does it have to implement Sized? It's a reference anyway.

trait SomeTrait {}

struct TraitImpl;

impl SomeTrait for TraitImpl {}

struct Container {
    trait_impl: TraitImpl,
}

impl Container {
    fn trait_ref(&self) -> &SomeTrait {
        &self.trait_impl
    }
}

fn take_trait_ref_generic<T: SomeTrait>(generic_trait_ref: &T) {}

fn main() {
    let container = Container { trait_impl: TraitImpl };

    /*Not possible*/
    take_trait_ref_generic(container.trait_ref());
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Sogomn
  • 304
  • 3
  • 16

1 Answers1

4

By default, all generic types on functions implicitly have the Sized bound, regardless of how they are used. You need to explicitly opt-out of that requirement using ?Sized:

fn take_trait_ref_generic<T>(generic_trait_ref: &T)
where 
    T: ?Sized + SomeTrait
{}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 4
    Ok is there a good reason for this rule? In other words, what would we lose if the compiler automatically added +?Sized on all bounds used only in references? – Pierre-Antoine May 23 '18 at 11:51