Support traits and structs with lifetime bounds (which are ignored)
[ldk-c-bindings] / c-bindings-gen / src / types.rs
index 979e951d76a3a25b9ebb8420becd371041932f9c..357fe4c815004a3ae775827a46ef3a34b013cc5b 100644 (file)
@@ -294,23 +294,28 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> {
                                &syn::TraitItem::Type(ref t) => {
                                        if t.default.is_some() || t.generics.lt_token.is_some() { unimplemented!(); }
                                        let mut bounds_iter = t.bounds.iter();
-                                       match bounds_iter.next().unwrap() {
-                                               syn::TypeParamBound::Trait(tr) => {
-                                                       assert_simple_bound(&tr);
-                                                       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.
-                                                               if path != "std::ops::Deref" && path != "core::ops::Deref" {
-                                                                       self.typed_generics.insert(&t.ident, path);
+                                       loop {
+                                               match bounds_iter.next().unwrap() {
+                                                       syn::TypeParamBound::Trait(tr) => {
+                                                               assert_simple_bound(&tr);
+                                                               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.
+                                                                       if path != "std::ops::Deref" && path != "core::ops::Deref" {
+                                                                               self.typed_generics.insert(&t.ident, path);
+                                                                       }
+                                                               } else { unimplemented!(); }
+                                                               for bound in bounds_iter {
+                                                                       if let syn::TypeParamBound::Trait(_) = bound { unimplemented!(); }
                                                                }
-                                                       } else { unimplemented!(); }
-                                               },
-                                               _ => unimplemented!(),
+                                                               break;
+                                                       },
+                                                       syn::TypeParamBound::Lifetime(_) => {},
+                                               }
                                        }
-                                       if bounds_iter.next().is_some() { unimplemented!(); }
                                },
                                _ => {},
                        }
@@ -1945,8 +1950,10 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                                DeclType::MirroredEnum if is_ref && ptr_for_ref => write!(w, "crate::{}::from_native(", decl_path).unwrap(),
                                                DeclType::MirroredEnum if is_ref => write!(w, "&crate::{}::from_native(", decl_path).unwrap(),
                                                DeclType::MirroredEnum => write!(w, "crate::{}::native_into(", decl_path).unwrap(),
-                                               DeclType::EnumIgnored {..}|DeclType::StructImported {..} if is_ref && ptr_for_ref && from_ptr =>
-                                                       write!(w, "crate::{} {{ inner: unsafe {{ (", decl_path).unwrap(),
+                                               DeclType::EnumIgnored {..}|DeclType::StructImported {..} if is_ref && from_ptr => {
+                                                       if !ptr_for_ref { write!(w, "&").unwrap(); }
+                                                       write!(w, "crate::{} {{ inner: unsafe {{ (", decl_path).unwrap()
+                                               },
                                                DeclType::EnumIgnored {..}|DeclType::StructImported {..} if is_ref => {
                                                        if !ptr_for_ref { write!(w, "&").unwrap(); }
                                                        write!(w, "crate::{} {{ inner: unsafe {{ ObjOps::nonnull_ptr_to_inner((", decl_path).unwrap()
@@ -1972,7 +1979,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> {
                                        DeclType::EnumIgnored { generic_param_count }|DeclType::StructImported { generic_param_count } if is_ref => {
                                                write!(w, " as *const {}<", full_path).unwrap();
                                                for _ in 0..*generic_param_count { write!(w, "_, ").unwrap(); }
-                                               if ptr_for_ref && from_ptr {
+                                               if from_ptr {
                                                        write!(w, ">) as *mut _ }}, is_owned: false }}").unwrap();
                                                } else {
                                                        write!(w, ">) as *mut _) }}, is_owned: false }}").unwrap();