Why is the following code an error? There is a blanket implementation for [T; N] into Vec<T>, so why does dyn Foo not match Fooable in this context? Is there a workaround which does not involve cloning the Fooable?
trait Foo {}
struct Fooable {}
impl Foo for Fooable {}
pub fn main() {
let bar: Vec<Box<dyn Foo>> = [
Box::new(Fooable {}),
].into();
}
Error:
error[E0277]: the trait bound `Vec<Box<dyn Foo>>: From<[Box<Fooable>; 1]>` is not satisfied
--> src/main.rs:10:7
|
10 | ].into();
| ^^^^ the trait `From<[Box<Fooable>; 1]>` is not implemented for `Vec<Box<dyn Foo>>`
|
= help: the following other types implement trait `From<T>`:
<Vec<T, A> as From<Box<[T], A>>>
<Vec<T, A> as From<VecDeque<T, A>>>
<Vec<T> as From<&[T]>>
<Vec<T> as From<&mut [T]>>
<Vec<T> as From<BinaryHeap<T>>>
<Vec<T> as From<Cow<'a, [T]>>>
<Vec<T> as From<[T; N]>>
<Vec<u8> as From<&str>>
and 2 others
= note: required because of the requirements on the impl of `Into<Vec<Box<dyn Foo>>>` for `[Box<Fooable>; 1]`
Playground
You're right. There's a blanket implementation for From<[T; n]> on Vec<T>. That means you can convert [T; n] into Vec<T> with From::from or Into::into.
More specifically, that means you can convert a [Box<Fooable>; 1] into a Vec<Box<Fooable>>, or a [Box<dyn Foo>; 1] into a Vec<Box<dyn Foo>>. However, you have a [Box<Fooable>; 1] and want a Vec<Box<dyn Foo>>, and since the T is different, the blanket impl doesn't apply.
Use an explicit cast to get the behavior you want. You just have to convince Rust that the type of the array is [Box<dyn Foo>; 1], not [Box<Fooable>; 1] as it originally infers.
let bar: Vec<Box<dyn Foo>> = [
Box::new(Fooable {}) as Box<dyn Foo>,
].into();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With