Bump refcount when cloning unwrapped nullables

This commit is contained in:
Richard Feldman 2022-05-25 09:02:44 -04:00
parent 54adbe3f44
commit 1001fdff82
No known key found for this signature in database
GPG key ID: 7E4127D1E4241798

View file

@ -616,6 +616,7 @@ fn add_tag_union(
} else { } else {
format!("impl Copy for {name} {{}}\n\n") format!("impl Copy for {name} {{}}\n\n")
}; };
let opt_impl = Some(format!("{opt_impl_prefix}impl Clone for {name}")); let opt_impl = Some(format!("{opt_impl_prefix}impl Clone for {name}"));
let mut buf = r#"fn clone(&self) -> Self { let mut buf = r#"fn clone(&self) -> Self {
let mut answer = unsafe { let mut answer = unsafe {
@ -932,10 +933,16 @@ fn write_nullable_unwrapped(
// The opaque struct for the tag union // The opaque struct for the tag union
{ {
let derive = derive_str(types.get(id), types); // These need their own Clone impl because they have
// a refcount to bump
let derive_extras = if types.get(id).has_float(types) {
""
} else {
", Eq, Ord, Hash"
};
let body = format!( let body = format!(
r#"{derive} r#"#[repr(C)]
#[repr(C)] #[derive(PartialEq, PartialOrd{derive_extras})]
pub struct {name} {{ pub struct {name} {{
pointer: *mut {wrapped_payload_type_name}, pointer: *mut {wrapped_payload_type_name},
}}"# }}"#
@ -1176,6 +1183,25 @@ pub struct {name} {{
); );
} }
// The Clone impl for the tag union
{
// Note that these never have Copy because they always contain a pointer.
let opt_impl = Some(format!("impl Clone for {name}"));
// Recursive tag unions need a custom Clone which bumps refcount.
let body = r#"fn clone(&self) -> Self {
roc_std::ReferenceCount::increment(self);
Self {
pointer: self.pointer
}
}
"#
.to_string();
add_decl(impls, opt_impl, architecture, body);
}
// The Drop impl for the tag union // The Drop impl for the tag union
{ {
let opt_impl = Some(format!("impl Drop for {name}")); let opt_impl = Some(format!("impl Drop for {name}"));