I have a type defined as follows (in another box):
trait Bar {
type Baz;
}
struct Foo<B: Bar, T> {
baz: B::Baz,
t: ::std::marker::PhantomData<T>
}
The type parameter Tis used to encode some data at compile time, and no instances of it will ever exist.
I would like to save several Foos, all with the same B, but with different Ts, in Vec. Each time I add or remove from it Vec, I will know the correct one Tfor the subject in other ways.
I know what I may have Vec<Box<Any>>, but I do not want to take the overhead of dynamic sending.
I decided to make it Vec<Foo<B, ()>>and, if necessary, convert it to the desired type. However, to my surprise, a function like the following is not allowed:
unsafe fn change_t<B: Bar, T, U>(foo: Foo<B, T>) -> Foo<B, U> {
::std::mem::transmute(foo)
}
This results in the following error:
error[E0512]: transmute called with types of different sizes
--> src/main.rs:13:5
|
13 | ::std::mem::transmute(foo)
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: source type: Foo<B, T> (size can vary because of <B as Bar>::Baz)
= note: target type: Foo<B, U> (size can vary because of <B as Bar>::Baz)
I find this very confusing since both types are the same B, so their B::Bazes should also be the same, and the type Tshould not affect the layout of the type. Why is this not allowed?
I was informed that this type transmuteleads to an error, even if there Tis no type parameter at all!
trait Bar {
type Baz;
}
struct Foo<B: Bar> {
baz: B::Baz,
}
unsafe fn change_t<B: Bar>(foo: B::Baz) -> B::Baz {
::std::mem::transmute(foo)
}
playground
Honestly, it’s impossible to translate even between B::Bazand B::Baz. Unless there are extremely subtle considerations that make this unsafe, this seems like a compiler error.