Use `GenericTypes`'s type resolver instead of re-resolving
[ldk-c-bindings] / c-bindings-gen / src / types.rs
index d15cec296571920519c78bdd1c7d0e5f939bf4b4..50800bb41ead1df865c57d4351fab8298378e28a 100644 (file)
@@ -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<Target = ConcreteThing>, 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<Target=X> as if it were just X (and
                                                                // implement Deref<Target=Self> 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<String> {
-               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<String> {
+               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)| {
@@ -1271,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 ***
        // ****************************
@@ -1567,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();
                                }