From: Matt Corallo Date: Mon, 23 Oct 2023 23:45:03 +0000 (+0000) Subject: Support trait impls on enums X-Git-Tag: v0.0.118.0^2~3 X-Git-Url: http://git.bitcoin.ninja/index.cgi?p=ldk-c-bindings;a=commitdiff_plain;h=1ec49fac7433e5b8693c3858a3e25998bc888eeb Support trait impls on enums Previously we'd only generate correct code for trait impls on structs, but there's no reason for that restriction. Here we also implement it on enums. --- diff --git a/c-bindings-gen/src/main.rs b/c-bindings-gen/src/main.rs index 6853534..7d6a452 100644 --- a/c-bindings-gen/src/main.rs +++ b/c-bindings-gen/src/main.rs @@ -94,11 +94,15 @@ fn maybe_convert_trait_impl(w: &mut W, trait_path: &syn::Path writeln!(w, ")").unwrap(); writeln!(w, "}}").unwrap(); + + writeln!(w, "#[allow(unused)]").unwrap(); + writeln!(w, "pub(crate) extern \"C\" fn {}_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z {{", for_obj).unwrap(); if has_inner { - writeln!(w, "pub(crate) extern \"C\" fn {}_write_void(obj: *const c_void) -> crate::c_types::derived::CVec_u8Z {{", for_obj).unwrap(); writeln!(w, "\tcrate::c_types::serialize_obj(unsafe {{ &*(obj as *const native{}) }})", for_obj).unwrap(); - writeln!(w, "}}").unwrap(); + } else { + writeln!(w, "\t{}_write(unsafe {{ &*(obj as *const {}) }})", for_obj, for_obj).unwrap(); } + writeln!(w, "}}").unwrap(); }, "lightning::util::ser::Readable"|"lightning::util::ser::ReadableArgs"|"lightning::util::ser::MaybeReadable" => { // Create the Result syn::Type @@ -553,6 +557,7 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty writeln!(w, "unsafe impl Send for {} {{}}", trait_name).unwrap(); writeln!(w, "unsafe impl Sync for {} {{}}", trait_name).unwrap(); + writeln!(w, "#[allow(unused)]").unwrap(); writeln!(w, "pub(crate) fn {}_clone_fields(orig: &{}) -> {} {{", trait_name, trait_name, trait_name).unwrap(); writeln!(w, "\t{} {{", trait_name).unwrap(); writeln!(w, "\t\tthis_arg: orig.this_arg,").unwrap(); @@ -1022,10 +1027,14 @@ fn writeln_impl(w: &mut W, w_uses: &mut HashSet(w: &mut W, w_uses: &mut HashSet crate::{} {{\n", ident, trait_obj.ident, ident, full_trait_path).unwrap(); writeln!(w, "\tcrate::{} {{", full_trait_path).unwrap(); - writeln!(w, "\t\tthis_arg: unsafe {{ ObjOps::untweak_ptr((*this_arg).inner) as *mut c_void }},").unwrap(); + if types.c_type_has_inner_from_path(&resolved_path) { + writeln!(w, "\t\tthis_arg: unsafe {{ ObjOps::untweak_ptr((*this_arg).inner) as *mut c_void }},").unwrap(); + } else { + writeln!(w, "\t\tthis_arg: unsafe {{ ObjOps::untweak_ptr(this_arg as *const {} as *mut {}) as *mut c_void }},", ident, ident).unwrap(); + } writeln!(w, "\t\tfree: None,").unwrap(); macro_rules! write_meth { @@ -1344,7 +1357,7 @@ fn writeln_impl(w: &mut W, w_uses: &mut HashSet *mut c_void {{", ident).unwrap(); - writeln!(w, "\tBox::into_raw(Box::new(unsafe {{ (*(this_ptr as *mut native{})).clone() }})) as *mut c_void", ident).unwrap(); + writeln!(w, "\tBox::into_raw(Box::new(unsafe {{ (*(this_ptr as *const native{})).clone() }})) as *mut c_void", ident).unwrap(); writeln!(w, "}}").unwrap(); writeln!(w, "#[no_mangle]").unwrap(); writeln!(w, "/// Creates a copy of the {}", ident).unwrap(); @@ -1935,7 +1948,18 @@ fn writeln_enum<'a, 'b, W: std::io::Write>(w: &mut W, e: &'a syn::ItemEnum, type writeln!(w, "pub extern \"C\" fn {}_clone(orig: &{}) -> {} {{", e.ident, e.ident, e.ident).unwrap(); writeln!(w, "\torig.clone()").unwrap(); writeln!(w, "}}").unwrap(); + writeln!(w, "#[allow(unused)]").unwrap(); + writeln!(w, "/// Used only if an object of this type is returned as a trait impl by a method").unwrap(); + writeln!(w, "pub(crate) extern \"C\" fn {}_clone_void(this_ptr: *const c_void) -> *mut c_void {{", e.ident).unwrap(); + writeln!(w, "\tBox::into_raw(Box::new(unsafe {{ (*(this_ptr as *const {})).clone() }})) as *mut c_void", e.ident).unwrap(); + writeln!(w, "}}").unwrap(); } + + writeln!(w, "#[allow(unused)]").unwrap(); + writeln!(w, "/// Used only if an object of this type is returned as a trait impl by a method").unwrap(); + writeln!(w, "pub(crate) extern \"C\" fn {}_free_void(this_ptr: *mut c_void) {{", e.ident).unwrap(); + writeln!(w, "\tlet _ = unsafe {{ Box::from_raw(this_ptr as *mut {}) }};\n}}", e.ident).unwrap(); + w.write_all(&constr).unwrap(); write_cpp_wrapper(cpp_headers, &format!("{}", e.ident), needs_free, None); }