'&self' needs to be Sized?

I have the following code:

fn takes_foo_ref<T: Foo>(_t: &T) { }

trait Foo {
    fn call_takes_ref(&self) {
        takes_foo_ref(self);
    }
}

Unfortunately, Rust seems to think that Self needs to be sized in order to pass self:

error[E0277]: the size for values of type `Self` cannot be known at compilation time
 --> src/lib.rs:5:9
  |
5 |         takes_foo_ref(self);
  |         ^^^^^^^^^^^^^ doesn't have a size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `Self`
  = note: to learn more, visit <https://doc.rust-lang.org/book/second-edition/ch19-04-advanced-types.html#dynamically-sized-types-and-sized>
  = help: consider adding a `where Self: std::marker::Sized` bound
note: required by `takes_foo_ref`
 --> src/lib.rs:1:1
  |
1 | fn takes_foo_ref<T: Foo>(_t: &T) { }
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This is surprising because self has type &Self, which is Sized. What am I missing here?

Self isn’t Sized, though, and takes_foo_ref has an implicit T: Sized bound. You can either force Foo implementations to be sized via trait Foo: Sized, or allow takes_foo_ref to take unsized T via T: ?Sized + Foo.

1 Like

Ah, of course! Thanks!