trait MyTrait{}
impl MyTrait for () {}
fn main() {
// Emits error
let a = Box::<dyn MyTrait>::new(());
// Works:
let a: Box<dyn MyTrait> = Box::new(());
}
The first row emits the following error:
error[E0599]: the function or associated item `new` exists for struct `Box<dyn MyTrait>`, but its trait bounds were not satisfied
--> src/main.rs:6:33
|
1 | trait MyTrait{}
| ------------- doesn't satisfy `dyn MyTrait: Sized`
...
6 | let a = Box::<dyn MyTrait>::new(());
| ^^^ function or associated item cannot be called on `Box<dyn MyTrait>` due to unsatisfied trait bounds
|
Does this behavior make any sense? What am I missing?
If Box::<dyn MyTrait>::new(()) were valid, it would imply passing a value of type dyn MyTrait to Box::new(), which is not possible because the language does not support handling dynamically sized values directly. So, instead, a Box<()> has to be created, then coerced to Box<dyn MyTrait>.
No. String literals already have type &'static str to begin with.
However, if you use byte string literals, like b"abc" in code like
let x: &[u8] = b"abc";
then you do have an unsized coercion, because b"abc" itself has type &'static [u8; 3], a reference to a fixed-size array. The code snippet above would use unsize-coercion to turn this “reference to an array” (&[u8; 3]) into a “reference to a slice” (&[u8]).
Byte-string literals in Rust serve to offer ASCII-encoded text directly as an array or slice of bytes, which can improve readability a lot in some use-cases.
The main reason why “ordinary” strings don’t work the same is likely as simple as the fact that there is no fixed-size string-type, comparable to arrays, in the standard library. (And that in turn is likely motivated by the fact that the memory-size of strings, i.e. number of bytes, for UTF-8 encoded strings can be a confusing or unhelpful measure in practice, so it’s useful not to hardcode these on the type level).