Pixel Pedals of Tomakomai

北海道苫小牧市出身の初老の日常

doesn't have a size known at compile-time

まだ時間がなくて詳しくは調べてないけど、こういう書き方はできない。まあそうかなと思う。

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>);