Simplify bindgen for into_ methods in tag unions

Thanks for the improvement @folkertdev!
This commit is contained in:
Richard Feldman 2022-05-12 17:03:16 -04:00
parent ce6c7f6024
commit ed769a7a3b
No known key found for this signature in database
GPG Key ID: 7E4127D1E4241798
2 changed files with 26 additions and 49 deletions

View File

@ -191,25 +191,13 @@ fn write_tag_union(
let payload_type = types.get(*payload_id);
let payload_type_name = type_name(*payload_id, types);
let (init_payload, get_payload, deref_for_as, self_for_into) = if payload_type
.has_pointer(types)
{
let (init_payload, get_payload, deref_for_as, self_for_into) =
if payload_type.has_pointer(types) {
(
"core::mem::ManuallyDrop::new(payload)",
format!(
r#"// We know our Drop impl was only ever going to run the payload's Drop impl,
// so returning the payload directly doesn't leak resources.
let variant = core::mem::replace(
&mut self.variant,
core::mem::transmute::<core::mem::MaybeUninit<{}>, {}>(
core::mem::MaybeUninit::uninit(),
),
);
core::mem::forget(self);
core::mem::ManuallyDrop::<{}>::into_inner(variant.{})"#,
variant_name, variant_name, payload_type_name, tag_name
"core::mem::ManuallyDrop::take(&mut self.variant.{})",
tag_name,
),
// Since this is a ManuallyDrop, our `as_` method will need
// to dereference the variant (e.g. `&self.variant.Foo`)

View File

@ -295,18 +295,7 @@ fn tag_union_aliased() {
/// Unsafely assume the given MyTagUnion has a .tag() of Foo and convert it to Foo's payload.
/// (always examine .tag() first to make sure this is the correct variant!)
pub unsafe fn into_Foo(mut self) -> roc_std::RocStr {
// We know our Drop impl was only ever going to run the payload's Drop impl,
// so returning the payload directly doesn't leak resources.
let variant = core::mem::replace(
&mut self.variant,
core::mem::transmute::<core::mem::MaybeUninit<union_MyTagUnion>, union_MyTagUnion>(
core::mem::MaybeUninit::uninit(),
),
);
core::mem::forget(self);
core::mem::ManuallyDrop::<roc_std::RocStr>::into_inner(variant.Foo)
core::mem::ManuallyDrop::take(&mut self.variant.Foo)
}
/// Unsafely assume the given MyTagUnion has a .tag() of Foo and return its payload.