Move overly-specific check to an assertion where its relevant
[ldk-c-bindings] / c-bindings-gen / src / types.rs
index ced1f34b0e91c31493127c14bf8c9e7db31748ac..c96a3b9a2fd51220057d89381c95e77e2f5d11a6 100644 (file)
@@ -65,6 +65,17 @@ pub fn path_matches_nongeneric(p: &syn::Path, exp: &[&str]) -> bool {
        true
 }
 
+pub fn string_path_to_syn_path(path: &str) -> syn::Path {
+       let mut segments = syn::punctuated::Punctuated::new();
+       for seg in path.split("::") {
+               segments.push(syn::PathSegment {
+                       ident: syn::Ident::new(seg, Span::call_site()),
+                       arguments: syn::PathArguments::None,
+               });
+       }
+       syn::Path { leading_colon: Some(syn::Token![::](Span::call_site())), segments }
+}
+
 #[derive(Debug, PartialEq)]
 pub enum ExportStatus {
        Export,
@@ -216,12 +227,13 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> {
                                                                non_lifetimes_processed = true;
                                                                if path != "std::ops::Deref" && path != "core::ops::Deref" {
                                                                        new_typed_generics.insert(&type_param.ident, Some(path));
-                                                               } else if trait_bound.path.segments.len() == 1 {
+                                                               } else {
                                                                        // If we're templated on Deref<Target = ConcreteThing>, store
                                                                        // the reference type in `default_generics` which handles full
                                                                        // types and not just paths.
                                                                        if let syn::PathArguments::AngleBracketed(ref args) =
                                                                                        trait_bound.path.segments[0].arguments {
+                                                                               assert_eq!(trait_bound.path.segments.len(), 1);
                                                                                for subargument in args.args.iter() {
                                                                                        match subargument {
                                                                                                syn::GenericArgument::Lifetime(_) => {},
@@ -257,7 +269,8 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> {
                                                if p.qself.is_some() { return false; }
                                                if p.path.leading_colon.is_some() { return false; }
                                                let mut p_iter = p.path.segments.iter();
-                                               if let Some(gen) = new_typed_generics.get_mut(&p_iter.next().unwrap().ident) {
+                                               let p_ident = &p_iter.next().unwrap().ident;
+                                               if let Some(gen) = new_typed_generics.get_mut(p_ident) {
                                                        if gen.is_some() { return false; }
                                                        if &format!("{}", p_iter.next().unwrap().ident) != "Target" {return false; }
 
@@ -270,7 +283,14 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> {
                                                                        if non_lifetimes_processed { return false; }
                                                                        non_lifetimes_processed = true;
                                                                        assert_simple_bound(&trait_bound);
-                                                                       *gen = Some(types.resolve_path(&trait_bound.path, None));
+                                                                       let resolved = types.resolve_path(&trait_bound.path, None);
+                                                                       let ty = syn::Type::Path(syn::TypePath {
+                                                                               qself: None, path: string_path_to_syn_path(&resolved)
+                                                                       });
+                                                                       let ref_ty = parse_quote!(&#ty);
+                                                                       self.default_generics.insert(p_ident, (ty, ref_ty));
+
+                                                                       *gen = Some(resolved);
                                                                }
                                                        }
                                                } else { return false; }
@@ -391,7 +411,7 @@ pub enum DeclType<'a> {
 }
 
 pub struct ImportResolver<'mod_lifetime, 'crate_lft: 'mod_lifetime> {
-       crate_name: &'mod_lifetime str,
+       pub crate_name: &'mod_lifetime str,
        dependencies: &'mod_lifetime HashSet<syn::Ident>,
        module_path: &'mod_lifetime str,
        imports: HashMap<syn::Ident, (String, syn::Path)>,
@@ -427,6 +447,10 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr
                                        new_path = format!("{}::{}{}", crate_name, $ident, $path_suffix);
                                        let crate_name_ident = format_ident!("{}", crate_name);
                                        path.push(parse_quote!(#crate_name_ident));
+                               } else if format!("{}", $ident) == "self" {
+                                       let mut path_iter = partial_path.rsplitn(2, "::");
+                                       path_iter.next().unwrap();
+                                       new_path = path_iter.next().unwrap().to_owned();
                                } else {
                                        new_path = format!("{}{}{}", partial_path, $ident, $path_suffix);
                                }
@@ -441,7 +465,8 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr
                        },
                        syn::UseTree::Name(n) => {
                                push_path!(n.ident, "");
-                               imports.insert(n.ident.clone(), (new_path, syn::Path { leading_colon: Some(syn::Token![::](Span::call_site())), segments: path }));
+                               let imported_ident = syn::Ident::new(new_path.rsplitn(2, "::").next().unwrap(), Span::call_site());
+                               imports.insert(imported_ident, (new_path, syn::Path { leading_colon: Some(syn::Token![::](Span::call_site())), segments: path }));
                        },
                        syn::UseTree::Group(g) => {
                                for i in g.items.iter() {
@@ -546,10 +571,6 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr
                Self { crate_name, dependencies, module_path, imports, declared, priv_modules }
        }
 
-       pub fn get_declared_type(&self, ident: &syn::Ident) -> Option<&DeclType<'crate_lft>> {
-               self.declared.get(ident)
-       }
-
        pub fn maybe_resolve_declared(&self, id: &syn::Ident) -> Option<&DeclType<'crate_lft>> {
                self.declared.get(id)
        }
@@ -562,17 +583,6 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr
                } else { None }
        }
 
-       pub fn maybe_resolve_non_ignored_ident(&self, id: &syn::Ident) -> Option<String> {
-               if let Some((imp, _)) = self.imports.get(id) {
-                       Some(imp.clone())
-               } else if let Some(decl_type) = self.declared.get(id) {
-                       match decl_type {
-                               DeclType::StructIgnored => None,
-                               _ => Some(self.module_path.to_string() + "::" + &format!("{}", id)),
-                       }
-               } else { None }
-       }
-
        pub fn maybe_resolve_path(&self, p: &syn::Path, generics: Option<&GenericTypes>) -> Option<String> {
                if let Some(gen_types) = generics {
                        if let Some(resp) = gen_types.maybe_resolve_path(p) {
@@ -715,6 +725,10 @@ impl FullLibraryAST {
 fn initial_clonable_types() -> HashSet<String> {
        let mut res = HashSet::new();
        res.insert("crate::c_types::u5".to_owned());
+       res.insert("crate::c_types::FourBytes".to_owned());
+       res.insert("crate::c_types::TwelveBytes".to_owned());
+       res.insert("crate::c_types::SixteenBytes".to_owned());
+       res.insert("crate::c_types::TwentyBytes".to_owned());
        res.insert("crate::c_types::ThirtyTwoBytes".to_owned());
        res.insert("crate::c_types::SecretKey".to_owned());
        res.insert("crate::c_types::PublicKey".to_owned());
@@ -722,8 +736,17 @@ fn initial_clonable_types() -> HashSet<String> {
        res.insert("crate::c_types::TxOut".to_owned());
        res.insert("crate::c_types::Signature".to_owned());
        res.insert("crate::c_types::RecoverableSignature".to_owned());
+       res.insert("crate::c_types::Bech32Error".to_owned());
        res.insert("crate::c_types::Secp256k1Error".to_owned());
        res.insert("crate::c_types::IOError".to_owned());
+       res.insert("crate::c_types::Error".to_owned());
+       res.insert("crate::c_types::Str".to_owned());
+
+       // Because some types are manually-mapped to CVec_u8Z we may end up checking if its clonable
+       // before we ever get to constructing the type fully via
+       // `write_c_mangled_container_path_intern` (which will add it here too), so we have to manually
+       // add it on startup.
+       res.insert("crate::c_types::derived::CVec_u8Z".to_owned());
        res
 }
 
@@ -741,7 +764,7 @@ pub struct CrateTypes<'a> {
        /// Aliases from paths to some other Type
        pub type_aliases: HashMap<String, syn::Type>,
        /// Value is an alias to Key (maybe with some generics)
-       pub reverse_alias_map: HashMap<String, Vec<(syn::Path, syn::PathArguments)>>,
+       pub reverse_alias_map: HashMap<String, Vec<(String, syn::PathArguments)>>,
        /// Template continer types defined, map from mangled type name -> whether a destructor fn
        /// exists.
        ///
@@ -785,7 +808,7 @@ impl<'a> CrateTypes<'a> {
 pub struct TypeResolver<'mod_lifetime, 'crate_lft: 'mod_lifetime> {
        pub module_path: &'mod_lifetime str,
        pub crate_types: &'mod_lifetime CrateTypes<'crate_lft>,
-       types: ImportResolver<'mod_lifetime, 'crate_lft>,
+       pub types: ImportResolver<'mod_lifetime, 'crate_lft>,
 }
 
 /// Returned by write_empty_rust_val_check_suffix to indicate what type of dereferencing needs to
@@ -831,7 +854,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
        /// Returns true we if can just skip passing this to C entirely
        fn no_arg_path_to_rust(&self, full_path: &str) -> &str {
                if full_path == "bitcoin::secp256k1::Secp256k1" {
-                       "secp256k1::SECP256K1"
+                       "secp256k1::global::SECP256K1"
                } else { unimplemented!(); }
        }
 
@@ -878,30 +901,34 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
 
                        "std::time::Duration"|"core::time::Duration" => Some("u64"),
                        "std::time::SystemTime" => Some("u64"),
-                       "std::io::Error" => Some("crate::c_types::IOError"),
+                       "std::io::Error"|"lightning::io::Error" => Some("crate::c_types::IOError"),
                        "core::fmt::Arguments" if is_ref => Some("crate::c_types::Str"),
 
                        "core::convert::Infallible" => Some("crate::c_types::NotConstructable"),
 
+                       "bitcoin::bech32::Error"|"bech32::Error"
+                               if !is_ref => Some("crate::c_types::Bech32Error"),
+                       "bitcoin::secp256k1::Error"|"secp256k1::Error"
+                               if !is_ref => Some("crate::c_types::Secp256k1Error"),
+
+                       "core::num::ParseIntError" => Some("crate::c_types::Error"),
+                       "core::str::Utf8Error" => Some("crate::c_types::Error"),
+
                        "bitcoin::bech32::u5"|"bech32::u5" => Some("crate::c_types::u5"),
                        "core::num::NonZeroU8" => Some("u8"),
 
-                       "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey"
-                               => Some("crate::c_types::PublicKey"),
-                       "bitcoin::secp256k1::Signature" => Some("crate::c_types::Signature"),
-                       "bitcoin::secp256k1::recovery::RecoverableSignature" => Some("crate::c_types::RecoverableSignature"),
-                       "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey"
-                               if is_ref  => Some("*const [u8; 32]"),
-                       "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey"
-                               if !is_ref => Some("crate::c_types::SecretKey"),
-                       "bitcoin::secp256k1::Error"|"secp256k1::Error"
-                               if !is_ref => Some("crate::c_types::Secp256k1Error"),
+                       "secp256k1::PublicKey"|"bitcoin::secp256k1::PublicKey" => Some("crate::c_types::PublicKey"),
+                       "bitcoin::secp256k1::ecdsa::Signature" => Some("crate::c_types::Signature"),
+                       "bitcoin::secp256k1::ecdsa::RecoverableSignature" => Some("crate::c_types::RecoverableSignature"),
+                       "bitcoin::secp256k1::SecretKey" if is_ref  => Some("*const [u8; 32]"),
+                       "bitcoin::secp256k1::SecretKey" if !is_ref => Some("crate::c_types::SecretKey"),
                        "bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice"),
                        "bitcoin::blockdata::script::Script" if !is_ref => Some("crate::c_types::derived::CVec_u8Z"),
                        "bitcoin::blockdata::transaction::OutPoint" => Some("crate::lightning::chain::transaction::OutPoint"),
                        "bitcoin::blockdata::transaction::Transaction"|"bitcoin::Transaction" => Some("crate::c_types::Transaction"),
                        "bitcoin::blockdata::transaction::TxOut" if !is_ref => Some("crate::c_types::TxOut"),
                        "bitcoin::network::constants::Network" => Some("crate::bitcoin::network::Network"),
+                       "bitcoin::util::address::WitnessVersion" => Some("crate::c_types::WitnessVersion"),
                        "bitcoin::blockdata::block::BlockHeader" if is_ref  => Some("*const [u8; 80]"),
                        "bitcoin::blockdata::block::Block" if is_ref  => Some("crate::c_types::u8slice"),
 
@@ -955,29 +982,31 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
 
                        "str" if is_ref => Some(""),
                        "alloc::string::String"|"String" => Some(""),
-                       "std::io::Error" if !is_ref => Some(""),
+                       "std::io::Error"|"lightning::io::Error" => Some(""),
                        // Note that we'll panic for String if is_ref, as we only have non-owned memory, we
                        // cannot create a &String.
 
                        "core::convert::Infallible" => Some("panic!(\"You must never construct a NotConstructable! : "),
 
+                       "bitcoin::bech32::Error"|"bech32::Error" if !is_ref => Some(""),
+                       "bitcoin::secp256k1::Error"|"secp256k1::Error" if !is_ref => Some(""),
+
+                       "core::num::ParseIntError" => Some("u8::from_str_radix(\" a\", 10).unwrap_err() /*"),
+                       "core::str::Utf8Error" => Some("core::str::from_utf8(&[0xff]).unwrap_err() /*"),
+
                        "std::time::Duration"|"core::time::Duration" => Some("core::time::Duration::from_secs("),
                        "std::time::SystemTime" => Some("(::std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs("),
 
                        "bitcoin::bech32::u5"|"bech32::u5" => Some(""),
                        "core::num::NonZeroU8" => Some("core::num::NonZeroU8::new("),
 
-                       "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey"
-                               if is_ref => Some("&"),
-                       "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey"
-                               => Some(""),
-                       "bitcoin::secp256k1::Signature" if is_ref => Some("&"),
-                       "bitcoin::secp256k1::Signature" => Some(""),
-                       "bitcoin::secp256k1::recovery::RecoverableSignature" => Some(""),
-                       "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey"
-                               if is_ref => Some("&::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *"),
-                       "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey"
-                               if !is_ref => Some(""),
+                       "bitcoin::secp256k1::PublicKey"|"secp256k1::PublicKey" if is_ref => Some("&"),
+                       "bitcoin::secp256k1::PublicKey"|"secp256k1::PublicKey" => Some(""),
+                       "bitcoin::secp256k1::ecdsa::Signature" if is_ref => Some("&"),
+                       "bitcoin::secp256k1::ecdsa::Signature" => Some(""),
+                       "bitcoin::secp256k1::ecdsa::RecoverableSignature" => Some(""),
+                       "bitcoin::secp256k1::SecretKey" if is_ref => Some("&::bitcoin::secp256k1::SecretKey::from_slice(&unsafe { *"),
+                       "bitcoin::secp256k1::SecretKey" if !is_ref => Some(""),
                        "bitcoin::blockdata::script::Script" if is_ref => Some("&::bitcoin::blockdata::script::Script::from(Vec::from("),
                        "bitcoin::blockdata::script::Script" if !is_ref => Some("::bitcoin::blockdata::script::Script::from("),
                        "bitcoin::blockdata::transaction::Transaction"|"bitcoin::Transaction" if is_ref => Some("&"),
@@ -985,6 +1014,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        "bitcoin::blockdata::transaction::OutPoint" => Some("crate::c_types::C_to_bitcoin_outpoint("),
                        "bitcoin::blockdata::transaction::TxOut" if !is_ref => Some(""),
                        "bitcoin::network::constants::Network" => Some(""),
+                       "bitcoin::util::address::WitnessVersion" => Some(""),
                        "bitcoin::blockdata::block::BlockHeader" => Some("&::bitcoin::consensus::encode::deserialize(unsafe { &*"),
                        "bitcoin::blockdata::block::Block" if is_ref => Some("&::bitcoin::consensus::encode::deserialize("),
 
@@ -1039,30 +1069,34 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
 
                        "str" if is_ref => Some(".into_str()"),
                        "alloc::string::String"|"String" => Some(".into_string()"),
-                       "std::io::Error" if !is_ref => Some(".to_rust()"),
+                       "std::io::Error"|"lightning::io::Error" => Some(".to_rust()"),
 
                        "core::convert::Infallible" => Some("\")"),
 
+                       "bitcoin::bech32::Error"|"bech32::Error" if !is_ref => Some(".into_rust()"),
+                       "bitcoin::secp256k1::Error"|"secp256k1::Error" if !is_ref => Some(".into_rust()"),
+
+                       "core::num::ParseIntError" => Some("*/"),
+                       "core::str::Utf8Error" => Some("*/"),
+
                        "std::time::Duration"|"core::time::Duration" => Some(")"),
                        "std::time::SystemTime" => Some("))"),
 
                        "bitcoin::bech32::u5"|"bech32::u5" => Some(".into()"),
                        "core::num::NonZeroU8" => Some(").expect(\"Value must be non-zero\")"),
 
-                       "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey"
-                               => Some(".into_rust()"),
-                       "bitcoin::secp256k1::Signature" => Some(".into_rust()"),
-                       "bitcoin::secp256k1::recovery::RecoverableSignature" => Some(".into_rust()"),
-                       "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey"
-                               if !is_ref => Some(".into_rust()"),
-                       "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey"
-                               if is_ref => Some("}[..]).unwrap()"),
+                       "bitcoin::secp256k1::PublicKey"|"secp256k1::PublicKey" => Some(".into_rust()"),
+                       "bitcoin::secp256k1::ecdsa::Signature" => Some(".into_rust()"),
+                       "bitcoin::secp256k1::ecdsa::RecoverableSignature" => Some(".into_rust()"),
+                       "bitcoin::secp256k1::SecretKey" if !is_ref => Some(".into_rust()"),
+                       "bitcoin::secp256k1::SecretKey" if is_ref => Some("}[..]).unwrap()"),
                        "bitcoin::blockdata::script::Script" if is_ref => Some(".to_slice()))"),
                        "bitcoin::blockdata::script::Script" if !is_ref => Some(".into_rust())"),
                        "bitcoin::blockdata::transaction::Transaction"|"bitcoin::Transaction" => Some(".into_bitcoin()"),
                        "bitcoin::blockdata::transaction::OutPoint" => Some(")"),
                        "bitcoin::blockdata::transaction::TxOut" if !is_ref => Some(".into_rust()"),
                        "bitcoin::network::constants::Network" => Some(".into_bitcoin()"),
+                       "bitcoin::util::address::WitnessVersion" => Some(".into()"),
                        "bitcoin::blockdata::block::BlockHeader" => Some(" }).unwrap()"),
                        "bitcoin::blockdata::block::Block" => Some(".to_slice()).unwrap()"),
 
@@ -1128,23 +1162,26 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
 
                        "std::time::Duration"|"core::time::Duration" => Some(""),
                        "std::time::SystemTime" => Some(""),
-                       "std::io::Error" if !is_ref => Some("crate::c_types::IOError::from_rust("),
+                       "std::io::Error"|"lightning::io::Error" => Some("crate::c_types::IOError::from_rust("),
                        "core::fmt::Arguments" => Some("alloc::format!(\"{}\", "),
 
                        "core::convert::Infallible" => Some("panic!(\"Cannot construct an Infallible: "),
 
-                       "bitcoin::bech32::u5"|"bech32::u5" => Some(""),
-
-                       "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey"
-                               => Some("crate::c_types::PublicKey::from_rust(&"),
-                       "bitcoin::secp256k1::Signature" => Some("crate::c_types::Signature::from_rust(&"),
-                       "bitcoin::secp256k1::recovery::RecoverableSignature" => Some("crate::c_types::RecoverableSignature::from_rust(&"),
-                       "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey"
-                               if is_ref => Some(""),
-                       "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey"
-                               if !is_ref => Some("crate::c_types::SecretKey::from_rust("),
+                       "bitcoin::bech32::Error"|"bech32::Error"
+                               if !is_ref => Some("crate::c_types::Bech32Error::from_rust("),
                        "bitcoin::secp256k1::Error"|"secp256k1::Error"
                                if !is_ref => Some("crate::c_types::Secp256k1Error::from_rust("),
+
+                       "core::num::ParseIntError" => Some("crate::c_types::Error { _dummy: 0 } /*"),
+                       "core::str::Utf8Error" => Some("crate::c_types::Error { _dummy: 0 } /*"),
+
+                       "bitcoin::bech32::u5"|"bech32::u5" => Some(""),
+
+                       "bitcoin::secp256k1::PublicKey"|"secp256k1::PublicKey" => Some("crate::c_types::PublicKey::from_rust(&"),
+                       "bitcoin::secp256k1::ecdsa::Signature" => Some("crate::c_types::Signature::from_rust(&"),
+                       "bitcoin::secp256k1::ecdsa::RecoverableSignature" => Some("crate::c_types::RecoverableSignature::from_rust(&"),
+                       "bitcoin::secp256k1::SecretKey" if is_ref => Some(""),
+                       "bitcoin::secp256k1::SecretKey" if !is_ref => Some("crate::c_types::SecretKey::from_rust("),
                        "bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice::from_slice(&"),
                        "bitcoin::blockdata::script::Script" if !is_ref => Some(""),
                        "bitcoin::blockdata::transaction::Transaction"|"bitcoin::Transaction" if is_ref => Some("crate::c_types::Transaction::from_bitcoin("),
@@ -1152,6 +1189,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        "bitcoin::blockdata::transaction::OutPoint" => Some("crate::c_types::bitcoin_to_C_outpoint("),
                        "bitcoin::blockdata::transaction::TxOut" if !is_ref => Some("crate::c_types::TxOut::from_rust("),
                        "bitcoin::network::constants::Network" => Some("crate::bitcoin::network::Network::from_bitcoin("),
+                       "bitcoin::util::address::WitnessVersion" => Some(""),
                        "bitcoin::blockdata::block::BlockHeader" if is_ref => Some("&local_"),
                        "bitcoin::blockdata::block::Block" if is_ref => Some("crate::c_types::u8slice::from_slice(&local_"),
 
@@ -1201,29 +1239,33 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
 
                        "std::time::Duration"|"core::time::Duration" => Some(".as_secs()"),
                        "std::time::SystemTime" => Some(".duration_since(::std::time::SystemTime::UNIX_EPOCH).expect(\"Times must be post-1970\").as_secs()"),
-                       "std::io::Error" if !is_ref => Some(")"),
+                       "std::io::Error"|"lightning::io::Error" => Some(")"),
                        "core::fmt::Arguments" => Some(").into()"),
 
                        "core::convert::Infallible" => Some("\")"),
 
-                       "bitcoin::bech32::u5"|"bech32::u5" => Some(".into()"),
-
-                       "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey"
-                               => Some(")"),
-                       "bitcoin::secp256k1::Signature" => Some(")"),
-                       "bitcoin::secp256k1::recovery::RecoverableSignature" => Some(")"),
-                       "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey"
+                       "bitcoin::secp256k1::Error"|"bech32::Error"
                                if !is_ref => Some(")"),
-                       "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey"
-                               if is_ref => Some(".as_ref()"),
                        "bitcoin::secp256k1::Error"|"secp256k1::Error"
                                if !is_ref => Some(")"),
+
+                       "core::num::ParseIntError" => Some("*/"),
+                       "core::str::Utf8Error" => Some("*/"),
+
+                       "bitcoin::bech32::u5"|"bech32::u5" => Some(".into()"),
+
+                       "bitcoin::secp256k1::PublicKey"|"secp256k1::PublicKey" => Some(")"),
+                       "bitcoin::secp256k1::ecdsa::Signature" => Some(")"),
+                       "bitcoin::secp256k1::ecdsa::RecoverableSignature" => Some(")"),
+                       "bitcoin::secp256k1::SecretKey" if !is_ref => Some(")"),
+                       "bitcoin::secp256k1::SecretKey" if is_ref => Some(".as_ref()"),
                        "bitcoin::blockdata::script::Script" if is_ref => Some("[..])"),
                        "bitcoin::blockdata::script::Script" if !is_ref => Some(".into_bytes().into()"),
                        "bitcoin::blockdata::transaction::Transaction"|"bitcoin::Transaction" => Some(")"),
                        "bitcoin::blockdata::transaction::OutPoint" => Some(")"),
                        "bitcoin::blockdata::transaction::TxOut" if !is_ref => Some(")"),
                        "bitcoin::network::constants::Network" => Some(")"),
+                       "bitcoin::util::address::WitnessVersion" => Some(".into()"),
                        "bitcoin::blockdata::block::BlockHeader" if is_ref => Some(""),
                        "bitcoin::blockdata::block::Block" if is_ref => Some(")"),
 
@@ -1251,8 +1293,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
        fn empty_val_check_suffix_from_path(&self, full_path: &str) -> Option<&str> {
                match full_path {
                        "lightning::ln::PaymentSecret" => Some(".data == [0; 32]"),
-                       "secp256k1::key::PublicKey"|"bitcoin::secp256k1::key::PublicKey" => Some(".is_null()"),
-                       "bitcoin::secp256k1::Signature" => Some(".is_null()"),
+                       "secp256k1::PublicKey"|"bitcoin::secp256k1::PublicKey" => Some(".is_null()"),
+                       "bitcoin::secp256k1::ecdsa::Signature" => Some(".is_null()"),
                        _ => None
                }
        }
@@ -1475,7 +1517,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
 
                                if let Some(t) = single_contained {
                                        match t {
-                                               syn::Type::Reference(_)|syn::Type::Path(_)|syn::Type::Slice(_) => {
+                                               syn::Type::Reference(_)|syn::Type::Path(_)|syn::Type::Slice(_)|syn::Type::Array(_) => {
                                                        let mut v = Vec::new();
                                                        let ret_ref = self.write_empty_rust_val_check_suffix(generics, &mut v, t);
                                                        let s = String::from_utf8(v).unwrap();
@@ -1553,9 +1595,6 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
        // *** Type definition during main.rs processing ***
        // *************************************************
 
-       pub fn get_declared_type(&'a self, ident: &syn::Ident) -> Option<&'a DeclType<'c>> {
-               self.types.get_declared_type(ident)
-       }
        /// Returns true if the object at the given path is mapped as X { inner: *mut origX, .. }.
        pub fn c_type_has_inner_from_path(&self, full_path: &str) -> bool {
                self.crate_types.opaques.get(full_path).is_some()
@@ -1580,10 +1619,6 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                self.types.maybe_resolve_ident(id)
        }
 
-       pub fn maybe_resolve_non_ignored_ident(&self, id: &syn::Ident) -> Option<String> {
-               self.types.maybe_resolve_non_ignored_ident(id)
-       }
-
        pub fn maybe_resolve_path(&self, p_arg: &syn::Path, generics: Option<&GenericTypes>) -> Option<String> {
                self.types.maybe_resolve_path(p_arg, generics)
        }
@@ -1778,7 +1813,6 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        syn::Type::Path(p) => {
                                let resolved = self.resolve_path(&p.path, generics);
                                if let Some(arr_ty) = self.is_real_type_array(&resolved) {
-                                       write!(w, ".data").unwrap();
                                        return self.write_empty_rust_val_check_suffix(generics, w, &arr_ty);
                                }
                                if self.crate_types.opaques.get(&resolved).is_some() {
@@ -1798,7 +1832,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                        syn::Type::Array(a) => {
                                if let syn::Expr::Lit(l) = &a.len {
                                        if let syn::Lit::Int(i) = &l.lit {
-                                               write!(w, " == [0; {}]", i.base10_digits()).unwrap();
+                                               write!(w, ".data == [0; {}]", i.base10_digits()).unwrap();
                                                EmptyValExpectedTy::NonPointer
                                        } else { unimplemented!(); }
                                } else { unimplemented!(); }
@@ -2844,7 +2878,6 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                assert!(self.write_c_type_intern(w, t, generics, false, false, ptr_for_ref, true, false));
        }
        pub fn understood_c_path(&self, p: &syn::Path) -> bool {
-               if p.leading_colon.is_some() { return false; }
                self.write_c_path_intern(&mut std::io::sink(), p, None, false, false, false, false, true)
        }
        pub fn understood_c_type(&self, t: &syn::Type, generics: Option<&GenericTypes>) -> bool {