X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=c-bindings-gen%2Fsrc%2Ftypes.rs;h=50800bb41ead1df865c57d4351fab8298378e28a;hb=19ebe5e21418685c3393e788a4af576830b983e7;hp=b1224a96d8be657623d32bdc670f21f6c842c27c;hpb=f160848382e6a1bc43dc100d77b96c4b4ecb3beb;p=ldk-c-bindings diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index b1224a9..50800bb 100644 --- a/c-bindings-gen/src/types.rs +++ b/c-bindings-gen/src/types.rs @@ -205,13 +205,12 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { if path_matches_nongeneric(&trait_bound.path, &["core", "clone", "Clone"]) { continue; } assert_simple_bound(&trait_bound); - if let Some(mut path) = types.maybe_resolve_path(&trait_bound.path, None) { + if let Some(path) = types.maybe_resolve_path(&trait_bound.path, None) { if types.skip_path(&path) { continue; } if path == "Sized" { continue; } if non_lifetimes_processed { return false; } non_lifetimes_processed = true; let new_ident = if path != "std::ops::Deref" && path != "core::ops::Deref" { - path = "crate::".to_string() + &path; Some(&trait_bound.path) } else if trait_bound.path.segments.len() == 1 { // If we're templated on Deref, store @@ -267,7 +266,7 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { if non_lifetimes_processed { return false; } non_lifetimes_processed = true; assert_simple_bound(&trait_bound); - *gen = ("crate::".to_string() + &types.resolve_path(&trait_bound.path, None), + *gen = (types.resolve_path(&trait_bound.path, None), Some(&trait_bound.path)); } } @@ -292,14 +291,13 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { match bounds_iter.next().unwrap() { syn::TypeParamBound::Trait(tr) => { assert_simple_bound(&tr); - if let Some(mut path) = types.maybe_resolve_path(&tr.path, None) { + if let Some(path) = types.maybe_resolve_path(&tr.path, None) { if types.skip_path(&path) { continue; } // In general we handle Deref as if it were just X (and // implement Deref for relevant types). We don't // bother to implement it for associated types, however, so we just // ignore such bounds. let new_ident = if path != "std::ops::Deref" && path != "core::ops::Deref" { - path = "crate::".to_string() + &path; Some(&tr.path) } else { None }; self.typed_generics.insert(&t.ident, (path, new_ident)); @@ -581,12 +579,12 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr } else { None } } - pub fn maybe_resolve_path(&self, p_arg: &syn::Path, generics: Option<&GenericTypes>) -> Option { - let p = if let Some(gen_types) = generics { - if let Some((_, synpath)) = gen_types.maybe_resolve_path(p_arg) { - synpath - } else { p_arg } - } else { p_arg }; + pub fn maybe_resolve_path(&self, p: &syn::Path, generics: Option<&GenericTypes>) -> Option { + if let Some(gen_types) = generics { + if let Some((resp, _)) = gen_types.maybe_resolve_path(p) { + return Some(resp.clone()); + } + } if p.leading_colon.is_some() { let mut res: String = p.segments.iter().enumerate().map(|(idx, seg)| { @@ -889,6 +887,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::SystemTime" => Some("u64"), "std::io::Error" => Some("crate::c_types::IOError"), + "core::convert::Infallible" => Some("crate::c_types::NotConstructable"), + "bech32::u5" => Some("crate::c_types::u5"), "core::num::NonZeroU8" => Some("u8"), @@ -967,6 +967,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { // 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! : "), + "std::time::Duration"|"core::time::Duration" => Some("std::time::Duration::from_secs("), "std::time::SystemTime" => Some("(::std::time::SystemTime::UNIX_EPOCH + std::time::Duration::from_secs("), @@ -1045,6 +1047,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "alloc::string::String"|"String" => Some(".into_string()"), "std::io::Error" if !is_ref => Some(".to_rust()"), + "core::convert::Infallible" => Some("\")"), + "std::time::Duration"|"core::time::Duration" => Some(")"), "std::time::SystemTime" => Some("))"), @@ -1136,6 +1140,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::SystemTime" => Some(""), "std::io::Error" if !is_ref => Some("crate::c_types::IOError::from_rust("), + "core::convert::Infallible" => Some("panic!(\"Cannot construct an Infallible: "), + "bech32::u5" => Some(""), "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey" @@ -1208,6 +1214,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "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(")"), + "core::convert::Infallible" => Some("\")"), + "bech32::u5" => Some(".into()"), "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey"|"secp256k1::key::PublicKey" @@ -1261,6 +1269,18 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } } + /// When printing a reference to the source crate's rust type, if we need to map it to a + /// different "real" type, it can be done so here. + /// This is useful to work around limitations in the binding type resolver, where we reference + /// a non-public `use` alias. + /// TODO: We should never need to use this! + fn real_rust_type_mapping<'equiv>(&self, thing: &'equiv str) -> &'equiv str { + match thing { + "lightning::io::Read" => "std::io::Read", + _ => thing, + } + } + // **************************** // *** Container Processing *** // **************************** @@ -1557,7 +1577,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { // If we're printing a generic argument, it needs to reference the crate, otherwise // the original crate: } else if self.maybe_resolve_path(&path, None).as_ref() == Some(&resolved) { - write!(w, "{}", resolved).unwrap(); + write!(w, "{}", self.real_rust_type_mapping(&resolved)).unwrap(); } else { write!(w, "crate::{}", resolved).unwrap(); }