Support traits with lifetime bounds (which are ignored)
[ldk-c-bindings] / c-bindings-gen / src / main.rs
index 51f67f750678fe9cfb6e0328c1ef0234b843153e..961669448fa8b39884c49eec895bfb9d275f1664 100644 (file)
@@ -482,13 +482,18 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                        &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) => {
-                                                               writeln!(w, "\ttype {} = crate::{};", t.ident, $type_resolver.resolve_path(&tr.path, Some(&gen_types))).unwrap();
-                                                       },
-                                                       _ => unimplemented!(),
+                                               loop {
+                                                       match bounds_iter.next().unwrap() {
+                                                               syn::TypeParamBound::Trait(tr) => {
+                                                                       writeln!(w, "\ttype {} = crate::{};", t.ident, $type_resolver.resolve_path(&tr.path, Some(&gen_types))).unwrap();
+                                                                       for bound in bounds_iter {
+                                                                               if let syn::TypeParamBound::Trait(_) = bound { unimplemented!(); }
+                                                                       }
+                                                                       break;
+                                                               },
+                                                               syn::TypeParamBound::Lifetime(_) => {},
+                                                       }
                                                }
-                                               if bounds_iter.next().is_some() { unimplemented!(); }
                                        },
                                        _ => unimplemented!(),
                                }
@@ -670,7 +675,7 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct,
                                                write!(w, "#[no_mangle]\npub extern \"C\" fn {}_get_{}(this_ptr: &{}) -> ", struct_name, $new_name, struct_name).unwrap();
                                                types.write_c_type(w, &ref_type, Some(&gen_types), true);
                                                write!(w, " {{\n\tlet mut inner_val = &mut this_ptr.get_native_mut_ref().{};\n\t", $real_name).unwrap();
-                                               let local_var = types.write_to_c_conversion_new_var(w, &format_ident!("inner_val"), &ref_type, Some(&gen_types), true);
+                                               let local_var = types.write_to_c_conversion_from_ownable_ref_new_var(w, &format_ident!("inner_val"), &ref_type, Some(&gen_types));
                                                if local_var { write!(w, "\n\t").unwrap(); }
                                                types.write_to_c_conversion_inline_prefix(w, &ref_type, Some(&gen_types), true);
                                                write!(w, "inner_val").unwrap();
@@ -1259,7 +1264,7 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                        write!(w, "#[no_mangle]\npub extern \"C\" fn {}_{}(", ident, m.sig.ident).unwrap();
                                                                        let ret_type = match &declared_type {
                                                                                DeclType::MirroredEnum => format!("{}", ident),
-                                                                               DeclType::StructImported => format!("{}", ident),
+                                                                               DeclType::StructImported {..} => format!("{}", ident),
                                                                                _ => unimplemented!(),
                                                                        };
                                                                        write_method_params(w, &m.sig, &ret_type, types, Some(&meth_gen_types), false, true);
@@ -1280,7 +1285,7 @@ fn writeln_impl<W: std::io::Write>(w: &mut W, i: &syn::ItemImpl, types: &mut Typ
                                                                        } else {
                                                                                match &declared_type {
                                                                                        DeclType::MirroredEnum => write!(w, "this_arg.to_native().{}(", m.sig.ident).unwrap(),
-                                                                                       DeclType::StructImported => {
+                                                                                       DeclType::StructImported {..} => {
                                                                                                if takes_owned_self {
                                                                                                        write!(w, "(*unsafe {{ Box::from_raw(this_arg.take_inner()) }}).{}(", m.sig.ident).unwrap();
                                                                                                } else if takes_mut_self {
@@ -1846,7 +1851,7 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a
                                                        ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"),
                                                }
                                                let struct_path = format!("{}::{}", module, s.ident);
-                                               crate_types.opaques.insert(struct_path, &s.ident);
+                                               crate_types.opaques.insert(struct_path, (&s.ident, &s.generics));
                                        }
                                },
                                syn::Item::Trait(t) => {
@@ -1891,7 +1896,7 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a
                                                                                hash_map::Entry::Vacant(e) => { e.insert(vec![(path_obj, args_obj)]); },
                                                                        }
 
-                                                                       crate_types.opaques.insert(type_path, t_ident);
+                                                                       crate_types.opaques.insert(type_path, (t_ident, &t.generics));
                                                                },
                                                                _ => {
                                                                        crate_types.type_aliases.insert(type_path, import_resolver.resolve_imported_refs((*t.ty).clone()));
@@ -1908,7 +1913,7 @@ fn walk_ast<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut CrateTypes<'a
                                                        ExportStatus::NotImplementable => panic!("(C-not implementable) must only appear on traits"),
                                                }
                                                let enum_path = format!("{}::{}", module, e.ident);
-                                               crate_types.opaques.insert(enum_path, &e.ident);
+                                               crate_types.opaques.insert(enum_path, (&e.ident, &e.generics));
                                        }
                                },
                                syn::Item::Enum(e) => {