From: Matt Corallo Date: Tue, 20 Aug 2024 18:31:29 +0000 (+0000) Subject: Stop relying on `impl Deref { type Target = Self; ...` X-Git-Tag: v0.0.124.0^2~17 X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=commitdiff_plain;h=fefaed28585675e2e792357768e6d9a11455c276;p=ldk-c-bindings Stop relying on `impl Deref { type Target = Self; ...` ... this has a tendency to cause `reached the recursion limit while auto-dereferencing` errors, and even a dumb struct copy suffices to avoid it. --- diff --git a/c-bindings-gen/src/main.rs b/c-bindings-gen/src/main.rs index 12d0772..dce1f87 100644 --- a/c-bindings-gen/src/main.rs +++ b/c-bindings-gen/src/main.rs @@ -646,12 +646,22 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty writeln!(w, " for {} {{", trait_name).unwrap(); impl_trait_for_c!(t, "", types, &syn::PathArguments::None); writeln!(w, "}}\n").unwrap(); + + writeln!(w, "struct {}Ref({});", trait_name, trait_name).unwrap(); + write!(w, "impl").unwrap(); + maybe_write_lifetime_generics(w, &t.generics, types); + write!(w, " rust{}", t.ident).unwrap(); + maybe_write_generics(w, &t.generics, &syn::PathArguments::None, types, false); + writeln!(w, " for {}Ref {{", trait_name).unwrap(); + impl_trait_for_c!(t, ".0", types, &syn::PathArguments::None); + writeln!(w, "}}\n").unwrap(); + writeln!(w, "// We're essentially a pointer already, or at least a set of pointers, so allow us to be used").unwrap(); writeln!(w, "// directly as a Deref trait in higher-level structs:").unwrap(); - writeln!(w, "impl core::ops::Deref for {} {{\n\ttype Target = Self;", trait_name).unwrap(); - writeln!(w, "\tfn deref(&self) -> &Self {{\n\t\tself\n\t}}\n}}").unwrap(); + writeln!(w, "impl core::ops::Deref for {} {{\n\ttype Target = {}Ref;", trait_name, trait_name).unwrap(); + writeln!(w, "\tfn deref(&self) -> &Self::Target {{\n\t\tunsafe {{ &*(self as *const _ as *const {}Ref) }}\n\t}}\n}}", trait_name).unwrap(); writeln!(w, "impl core::ops::DerefMut for {} {{", trait_name).unwrap(); - writeln!(w, "\tfn deref_mut(&mut self) -> &mut Self {{\n\t\tself\n\t}}\n}}").unwrap(); + writeln!(w, "\tfn deref_mut(&mut self) -> &mut {}Ref {{\n\t\tunsafe {{ &mut *(self as *mut _ as *mut {}Ref) }}\n\t}}\n}}", trait_name, trait_name).unwrap(); } writeln!(w, "/// Calls the free function if one is set").unwrap();