use std::any::type_name;
struct A {}
trait Trait {
fn show(&self) {
println!("hello")
}
}
impl Trait for A {}
impl Trait for &A {}
impl Trait for &dyn Trait {}
// See the question below.
fn doit<T: Trait + ?Sized>(x: T) {
println!("T == {}", type_name::<T>());
x.show()
}
fn main() {
let a: Box<dyn Trait> = Box::new(A {});
doit(a.as_ref());
}
To what type does T get inferred? If it is &dyn T which I expect, then why is it not Sized, since I have then x: &dyn Trait which is for sure Sized?
error[E0277]: the size for values of type `T` cannot be known at compilation time
|
17 | fn doit<T: I + ?Sized>(x: T) {
| - ^ doesn't have a size known at compile-time
| |
| this type parameter needs to be `Sized`
|
= help: unsized fn params are gated as an unstable feature
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
17 - fn doit<T: I + ?Sized>(x: T) {
17 + fn doit<T: I>(x: T) {
|
help: function arguments must have a statically known size, borrowed types always have a known size
|
17 | fn doit<T: I + ?Sized>(x: &T) {
| +
Type inference has nothing to do with your error. You can never create a function that takes an unsized T as a parameter directly, without any sort of indirection, like & or Box. The size of all function parameters (and the return type as well) must be known at compile time. Removing the ?Sized from T will make doit compile.
You say takes an unsized T as parameter, that is the x: T above.
I thought my doit function will check the ?Sized := can be Sized or unsized when it matched the T -> In my case T is &dyn Trait and that makes some confusion. So when are the bounds checked?
&dyn Traitis sized because it's a reference. When you write T: ?Sized you're allowing the substitution of an unsized type directly; that is, we may have T = dyn Trait, so the signature becomes:
fn doit(x: dyn Trait) {...}
which is accepting an unsized value directly, without any reference or any other container, which is not something that is currently permitted. So, your function definition is invalid by itself — the call site doesn't matter.
But if your intent is to be able to pass &dyn Trait, not dyn Trait, then you don't need the ?Sized. Remove it and the program will compile.