I've been looking at the current Rust glue spec's output for tag unions. The generated .get_discriminant() function uses mem::transmute to get at the tag union's raw bytes, then uses pointer arithmatic to pull the discriminant out:
pub fn discriminant(&self) -> discriminant_U1 {
unsafe {
let bytes = core::mem::transmute::<&Self, &[u8; core::mem::size_of::<Self>()]>(self);
core::mem::transmute::<u8, discriminant_U1>(*bytes.as_ptr().add(24))
}
}
(same goes for set_discriminant()`)
I'm wondering why the decision was made to do this instead of accessing the discriminant field directly?
Notable here too is that the .is_<variant>()
functions do access the field directly:
pub fn is_VariantA(&self) -> bool {
matches!(self.discriminant, discriminant_U1::VariantA)
}
pub fn is_VariantB(&self) -> bool {
matches!(self.discriminant, discriminant_U1::VariantB)
}
pub fn is_VariantC(&self) -> bool {
matches!(self.discriminant, discriminant_U1::VariantC)
}
not sure, maybe because then the same skeleton can sort of be reused? anyway, the field access method is better of course
Last updated: Jul 06 2025 at 12:14 UTC