Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Rust not allow coercion to trait objects inside containers?

I have a Vec<Box<T>> where T implements Foo. Why can I not coerce it to a Vec<Box<Foo>> even though I can coerce anything of type Box<T> into a Box<Foo>? Why does the below code not compile?

use std::vec;

trait Foo {}

struct Bar {}

impl Foo for Bar {}

fn main() {
    let v = vec![Box::new(Bar {})];
    let v_1 = v as Vec<Box<Foo>>;
}
like image 573
Jason Teplitz Avatar asked Jan 27 '17 08:01

Jason Teplitz


People also ask

What is coercion in Rust?

Type coercions are implicit operations that change the type of a value. They happen automatically at specific locations and are highly restricted in what types actually coerce. Any conversions allowed by coercion can also be explicitly performed by the type cast operator, as .

What is rust trait object?

A trait object is an opaque value of another type that implements a set of traits. The set of traits is made up of an object safe base trait plus any number of auto traits. Trait objects implement the base trait, its auto traits, and any supertraits of the base trait.


1 Answers

Because Box<Bar> is a different size than Box<Foo>. The coercion is allowed on a single value, but here you'd have to resize the whole vector. The book goes into some detail on this in the section on Representation of Trait Objects. Short version: Box<Bar> is a pointer to a value. Box<Foo> is a pointer to a value and a pointer to a vtable.

like image 111
DK. Avatar answered Oct 11 '22 15:10

DK.