Drop `empty_val_check_suffix_from_path` for Signature as its unused
[ldk-c-bindings] / c-bindings-gen / src / types.rs
index 6d97ccc32ffb10357bf020c2eefe8c56bea01b78..007a05b1fc8a4e4e97389cc6871a250248680f1a 100644 (file)
@@ -225,7 +225,8 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> {
                                                                if path == "Sized" { continue; }
                                                                if non_lifetimes_processed { return false; }
                                                                non_lifetimes_processed = true;
-                                                               if path != "std::ops::Deref" && path != "core::ops::Deref" {
+                                                               if path != "std::ops::Deref" && path != "core::ops::Deref" &&
+                                                                       path != "std::ops::DerefMut" && path != "core::ops::DerefMut"  {
                                                                        let p = string_path_to_syn_path(&path);
                                                                        let ref_ty = parse_quote!(&#p);
                                                                        let mut_ref_ty = parse_quote!(&mut #p);
@@ -347,8 +348,24 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> {
                                                                        // implement Deref<Target=Self> for relevant types). We don't
                                                                        // bother to implement it for associated types, however, so we just
                                                                        // ignore such bounds.
-                                                                       if path != "std::ops::Deref" && path != "core::ops::Deref" {
+                                                                       if path != "std::ops::Deref" && path != "core::ops::Deref" &&
+                                                                       path != "std::ops::DerefMut" && path != "core::ops::DerefMut" {
                                                                                self.typed_generics.insert(&t.ident, path);
+                                                                       } else {
+                                                                               let last_seg_args = &tr.path.segments.last().unwrap().arguments;
+                                                                               if let syn::PathArguments::AngleBracketed(args) = last_seg_args {
+                                                                                       assert_eq!(args.args.len(), 1);
+                                                                                       if let syn::GenericArgument::Binding(binding) = &args.args[0] {
+                                                                                               assert_eq!(format!("{}", binding.ident), "Target");
+                                                                                               if let syn::Type::Path(p) = &binding.ty {
+                                                                                                       // Note that we are assuming the order of type
+                                                                                                       // declarations here, but that should be easy
+                                                                                                       // to handle.
+                                                                                                       let real_path = self.maybe_resolve_path(&p.path).unwrap();
+                                                                                                       self.typed_generics.insert(&t.ident, real_path.clone());
+                                                                                               } else { unimplemented!(); }
+                                                                                       } else { unimplemented!(); }
+                                                                               } else { unimplemented!(); }
                                                                        }
                                                                } else { unimplemented!(); }
                                                                for bound in bounds_iter {
@@ -548,6 +565,7 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr
                Self::insert_primitive(&mut imports, "bool");
                Self::insert_primitive(&mut imports, "u128");
                Self::insert_primitive(&mut imports, "i64");
+               Self::insert_primitive(&mut imports, "f64");
                Self::insert_primitive(&mut imports, "u64");
                Self::insert_primitive(&mut imports, "u32");
                Self::insert_primitive(&mut imports, "u16");
@@ -661,12 +679,41 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr
                                Some(first_seg_str + &remaining)
                        } else if first_seg_str == "crate" {
                                Some(self.crate_name.to_owned() + &remaining)
+                       } else if self.library.modules.get(&format!("{}::{}", self.module_path, first_seg.ident)).is_some() {
+                               Some(format!("{}::{}{}", self.module_path, first_seg.ident, remaining))
                        } else { None }
                }
        }
 
        pub fn maybe_resolve_path(&self, p: &syn::Path, generics: Option<&GenericTypes>) -> Option<String> {
                self.maybe_resolve_imported_path(p, generics).map(|mut path| {
+                       if path == "core::ops::Deref" || path == "core::ops::DerefMut" {
+                               let last_seg = p.segments.last().unwrap();
+                               if let syn::PathArguments::AngleBracketed(args) = &last_seg.arguments {
+                                       assert_eq!(args.args.len(), 1);
+                                       if let syn::GenericArgument::Binding(binding) = &args.args[0] {
+                                               if let syn::Type::Path(p) = &binding.ty {
+                                                       if let Some(inner_ty) = self.maybe_resolve_path(&p.path, generics) {
+                                                               let mut module_riter = inner_ty.rsplitn(2, "::");
+                                                               let ty_ident = module_riter.next().unwrap();
+                                                               let module_name = module_riter.next().unwrap();
+                                                               let module = self.library.modules.get(module_name).unwrap();
+                                                               for item in module.items.iter() {
+                                                                       match item {
+                                                                               syn::Item::Trait(t) => {
+                                                                                       if t.ident == ty_ident {
+                                                                                               path = inner_ty;
+                                                                                               break;
+                                                                                       }
+                                                                               },
+                                                                               _ => {}
+                                                                       }
+                                                               }
+                                                       }
+                                               } else { unimplemented!(); }
+                                       } else { unimplemented!(); }
+                               }
+                       }
                        loop {
                                // Now that we've resolved the path to the path as-imported, check whether the path
                                // is actually a pub(.*) use statement and map it to the real path.
@@ -950,6 +997,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                match full_path {
                        "bool" => true,
                        "i64" => true,
+                       "f64" => true,
                        "u64" => true,
                        "u32" => true,
                        "u16" => true,
@@ -1495,7 +1543,6 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
        fn empty_val_check_suffix_from_path(&self, full_path: &str) -> Option<&str> {
                match full_path {
                        "secp256k1::PublicKey"|"bitcoin::secp256k1::PublicKey" => Some(".is_null()"),
-                       "bitcoin::secp256k1::ecdsa::Signature" => Some(".is_null()"),
                        _ => None
                }
        }
@@ -2854,7 +2901,14 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                                                        generics, &subtype, is_ref, is_mut, ptr_for_ref, true);
                                                        }
                                                } else {
-                                                       let id = subtype.rsplitn(2, ':').next().unwrap(); // Get the "Base" name of the resolved type
+                                                       let mut resolved = Vec::new();
+                                                       let id =
+                                                               if self.write_c_path_intern(&mut resolved, &$p_arg.path, generics, false, false, false, false, false) {
+                                                                       let inner = std::str::from_utf8(&resolved).unwrap();
+                                                                       inner.rsplitn(2, "::").next().unwrap()
+                                                               } else {
+                                                                       subtype.rsplitn(2, "::").next().unwrap()
+                                                               };
                                                        write!(w, "{}", id).unwrap();
                                                        write!(mangled_type, "{}", id).unwrap();
                                                        if let Some(w2) = $extra_write as Option<&mut Vec<u8>> {
@@ -2888,9 +2942,9 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                                                } else { return false; }
                                                        } else if let syn::Type::Array(_) = elem {
                                                                let mut resolved = Vec::new();
-                                                               if !self.write_c_type_intern(&mut resolved, &elem, generics, false, false, true, false, true) { return false; }
+                                                               if !self.write_c_type_intern(&mut resolved, &elem, generics, false, false, false, false, false) { return false; }
                                                                let array_inner = String::from_utf8(resolved).unwrap();
-                                                               let arr_name = array_inner.split("::").last().unwrap();
+                                                               let arr_name = array_inner.rsplitn(2, "::").next().unwrap();
                                                                write!(w, "{}", arr_name).unwrap();
                                                                write!(mangled_type, "{}", arr_name).unwrap();
                                                        } else { return false; }
@@ -3017,7 +3071,9 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                        // If this is a no-export'd crate and there's only one implementation in the
                                        // whole crate, just treat it as a reference to whatever the implementor is.
                                        if with_ref_lifetime {
-                                               write!(w, "&'static crate::{}", trait_impls[0]).unwrap();
+                                               // Hope we're being printed in function generics and let rustc derive the
+                                               // type.
+                                               write!(w, "_").unwrap();
                                        } else {
                                                write!(w, "&crate::{}", trait_impls[0]).unwrap();
                                        }