]> git.bitcoin.ninja Git - ldk-c-bindings/commitdiff
Handle writing Rust types for single-impl traits
authorMatt Corallo <git@bluematt.me>
Mon, 26 Aug 2024 19:15:57 +0000 (19:15 +0000)
committerMatt Corallo <git@bluematt.me>
Tue, 3 Sep 2024 18:55:34 +0000 (18:55 +0000)
Single-impl traits which are marked no-export (like
`AChannelManager` in LDK) are mapped as the singular implementing
type, rather than a full-blown trait.

Here we handle this case when writing Rust objects (generally used
in writing generic bounds).

c-bindings-gen/src/types.rs

index 51efa247a73514eee5c2e4bede5bc796780cf529..b8c8b4b9e077568809c753f9d125afd0a2cb4762 100644 (file)
@@ -1983,11 +1983,19 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                        // the original crate.
                                        write!(w, "{}", self.real_rust_type_mapping(&resolved)).unwrap();
                                } else {
+                                       if let Some(trait_impls) = self.crate_types.traits_impld.get(&resolved) {
+                                               if self.crate_types.traits.get(&resolved).is_none() && trait_impls.len() == 1 {
+                                                       write!(w, "crate::{}", trait_impls[0]).unwrap();
+                                                       return;
+                                               }
+                                       }
                                        write!(w, "crate::{}", resolved).unwrap();
                                }
                        }
-                       if let syn::PathArguments::AngleBracketed(args) = &path.segments.iter().last().unwrap().arguments {
-                               self.write_rust_generic_arg(w, generics_resolver, args.args.iter(), with_ref_lifetime);
+                       if !generated_crate_ref {
+                               if let syn::PathArguments::AngleBracketed(args) = &path.segments.iter().last().unwrap().arguments {
+                                       self.write_rust_generic_arg(w, generics_resolver, args.args.iter(), with_ref_lifetime);
+                               }
                        }
                } else {
                        if path.leading_colon.is_some() {
@@ -2051,7 +2059,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                }
                                if let Some(resolved_ty) = self.maybe_resolve_path(&p.path, generics) {
                                        generate_crate_ref |= self.maybe_resolve_path(&p.path, None).as_ref() != Some(&resolved_ty);
-                                       if self.crate_types.traits.get(&resolved_ty).is_none() { generate_crate_ref = false; }
+                                       let mut is_trait = self.crate_types.traits.get(&resolved_ty).is_some();
+                                       is_trait |= self.crate_types.traits_impld.get(&resolved_ty).is_some();
+                                       if !is_trait {
+                                               generate_crate_ref = false;
+                                       }
                                }
                                self.write_rust_path(w, generics, &p.path, with_ref_lifetime, generate_crate_ref);
                        },