I have this fairly straightforward Rust program:
use std::ops::Deref;
trait Foo {
fn foo(&self);
}
impl Foo for () {
fn foo(&self) {
printl
The error message wasn't stellar when this question was asked. The same code (Playground) shows a better error message today:
error[E0277]: the size for values of type `dyn Foo` cannot be known at compilation time
--> src/main.rs:26:3
|
26 | call_foo(&foo);
| ^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn Foo`
= note: to learn more, visit
= note: required because of the requirements on the impl of `Foo` for `std::boxed::Box`
note: required by `call_foo`
--> src/main.rs:20:1
|
20 | fn call_foo(foo: &F) where F: Foo {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The error message links to The Rust Programming Language Book, Chapter 19, section 4, "Dynamically sized types and the Sized trait".
The problem arises because by default, a generic type parameter is assumed to be Sized
. However, a trait object (the dyn Foo
in Box
) does not have a known size. That's acceptable in this case, so we modify the blanket implementation to allow boxes things with an unknown size:
impl Foo for Box
where F: Foo
Here is the fixed code, updated to the Rust 2018 edition:
trait Foo {
fn foo(&self);
}
impl Foo for () {
fn foo(&self) {
println!("hello world");
}
}
impl Foo for Box
where F: Foo
{
fn foo(&self) {
(**self).foo()
}
}
fn call_foo(foo: &F)
where F: Foo
{
foo.foo()
}
fn main() {
let foo: Box = Box::new(());
call_foo(&foo);
}