まだ時間がなくて詳しくは調べてないけど、こういう書き方はできない。まあそうかなと思う。
use std::fmt::Display; struct S<T> (T); fn main() { let s: Box<S<dyn Display>> = Box::new(S("")); }
Compiling playground v0.0.1 (/playground)
error[E0277]: the size for values of type `dyn std::fmt::Display` cannot be known at compilation time
--> src/lib.rs:6:12
|
3 | struct S<T> (T);
| ---------------- required by `S`
...
6 | let s: Box<S<dyn Display>> = Box::new(S(""));
| ^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn std::fmt::Display`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`.
To learn more, run the command again with --verbose.
S をとっぱらって Box で直接包むと Sized 扱いになるのでコンパイルできる。 これは、 Box がコンパイラに特別視されてるからなのかな?
2020-05-23 追記
型変数がデフォルトで Sized なのが原因だった。 ?Sized を明確に指定すれば問題ない。
use std::fmt::Display; struct S<T> (T) where T: ?Sized; fn main() { let _s: Box<S<dyn Display>> = Box::new(S("")); }
Box も 特別ではない 。
pub struct Box<T: ?Sized>(Unique<T>);