#converting owned values to owned enum variants
12 messages · Page 1 of 1 (latest)
Unless T is your only variant (and you mark E as #[repr(transparent)]) then this is fundamentally not possible, because T and E::T will not have the same memory layout.
You can't reinterpret the reference because you need to be adding extra information to the value (its discriminant)
=/ well fuck
i need to rethink my design
If you provide a bit more context to explain why you ended up in a situation where you needed that conversion, then we could probably help a bit more ;)
context stack:
- interpreter for dynamically typed lang
- objects represented in one big enum
- need a method on variants to convert it into the big enum
- all of the variants are
Cloneable except for one which has aBox<FnMut(...) -> ...> - if i can transform
&selfinto&Object::...(self)i could return it and avoidCloneing it - this question
mhh, could this conversion be changed to accept owned values and return an owned enum instead ?
There is an unsafe way, but it has a lot of considerations:
If you make the enum #[repr(u8)] (or any other integer repr, but not a #[repr(C, Int)]), then it has a stable layout (described here: https://rust-lang.github.io/rfcs/2195-really-tagged-unions.html). You could mimic that layout with a #[repr(C)] struct, and then you'd be allowed to transmute between them.
To clarify:
#[repr(u8)]
enum TwoCases {
A(u8, u16),
B(u16),
}
```Has the same layout as
```rs
union TwoCasesRepr {
A: TwoCasesVariantA,
B: TwoCasesVariantB,
}
#[repr(u8)]
enum TwoCasesTag { A, B }
#[repr(C)]
struct TwoCasesVariantA(TwoCasesTag, u8, u16);
#[repr(C)]
struct TwoCasesVariantB(TwoCasesTag, u16);
```As a consequence, `transmute::<TwoCasesVariantB, TwoCases>(variant_b)` is a correct operation.
As for `transmute::<&TwoCasesVariantB, &TwoCases>(&variant_b)`, that one is _also_ correct, **provided the aligment lines up**. If the enum as a higher alignment than its "variant struct", then this isn't always correct. (also, put this in a helper function. By default, `transmute` doesn't "connect" the lifetimes, it just makes the output have an unbounded one)
(get #dark-arts to doublecheck this, tho, if you choose to follow this idea)
the solution was to in fact
learn how the fuck rust actually works
i meant fn, not Fn
so im afraid im gonna have to pull an xkcd 979