]> git.bitcoin.ninja Git - ldk-c-bindings/blobdiff - c-bindings-gen/src/main.rs
Handle no-export traits which are only implemented once as the implementor
[ldk-c-bindings] / c-bindings-gen / src / main.rs
index 1b54d16de5a8c830220e408e13ae7d1d477a37fa..0a1d22a119aa9ea9a66aeb0984ae67877b9feda3 100644 (file)
@@ -366,9 +366,6 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                                writeln!(extra_headers, "struct LDK{};", trait_name).unwrap();
                                                continue;
                                        }
-                                       // Sadly, this currently doesn't do what we want, but it should be easy to get
-                                       // cbindgen to support it. See https://github.com/eqrion/cbindgen/issues/531
-                                       writeln!(w, "\t#[must_use]").unwrap();
                                }
 
                                let mut cpp_docs = Vec::new();
@@ -535,7 +532,12 @@ fn writeln_trait<'a, 'b, W: std::io::Write>(w: &mut W, t: &'a syn::ItemTrait, ty
                                                                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 { panic!("11"); }
+                                                                               if let syn::TypeParamBound::Trait(t) = bound {
+                                                                                       // We only allow for `?Sized` here.
+                                                                                       if let syn::TraitBoundModifier::Maybe(_) = t.modifier {} else { panic!(); }
+                                                                                       assert_eq!(t.path.segments.len(), 1);
+                                                                                       assert_eq!(format!("{}", t.path.segments[0].ident), "Sized");
+                                                                               }
                                                                        }
                                                                        break;
                                                                },
@@ -803,7 +805,7 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct,
                                define_field!(('a' as u8 + idx as u8) as char, ('0' as u8 + idx as u8) as char, field);
                        }
                }
-               _ => unimplemented!()
+               syn::Fields::Unit => {},
        }
 
        if all_fields_settable {
@@ -826,7 +828,7 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct,
                                        types.write_c_type(w, &field.ty, Some(&gen_types), false);
                                }
                        }
-                       _ => unreachable!()
+                       syn::Fields::Unit => {},
                }
                write!(w, ") -> {} {{\n\t", struct_name).unwrap();
                match &s.fields {
@@ -846,7 +848,7 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct,
                                        }
                                }
                        },
-                       _ => unreachable!()
+                       syn::Fields::Unit => {},
                }
                write!(w, "{} {{ inner: ObjOps::heap_alloc(", struct_name).unwrap();
                match &s.fields {
@@ -874,7 +876,7 @@ fn writeln_struct<'a, 'b, W: std::io::Write>(w: &mut W, s: &'a syn::ItemStruct,
                                }
                                write!(w, "\t)").unwrap();
                        },
-                       _ => unreachable!()
+                       syn::Fields::Unit => write!(w, "{}::{} {{}}", types.module_path, struct_name).unwrap(),
                }
                writeln!(w, "), is_owned: true }}\n}}").unwrap();
        }
@@ -2198,9 +2200,13 @@ fn walk_private_mod<'a>(ast_storage: &'a FullLibraryAST, orig_crate: &str, modul
                                        if let Some(trait_path) = i.trait_.as_ref() {
                                                if let Some(tp) = import_resolver.maybe_resolve_path(&trait_path.1, None) {
                                                        if let Some(sp) = import_resolver.maybe_resolve_path(&p.path, None) {
-                                                               match crate_types.trait_impls.entry(sp) {
-                                                                       hash_map::Entry::Occupied(mut e) => { e.get_mut().push(tp); },
-                                                                       hash_map::Entry::Vacant(e) => { e.insert(vec![tp]); },
+                                                               match crate_types.trait_impls.entry(sp.clone()) {
+                                                                       hash_map::Entry::Occupied(mut e) => { e.get_mut().push(tp.clone()); },
+                                                                       hash_map::Entry::Vacant(e) => { e.insert(vec![tp.clone()]); },
+                                                               }
+                                                               match crate_types.traits_impld.entry(tp) {
+                                                                       hash_map::Entry::Occupied(mut e) => { e.get_mut().push(sp); },
+                                                                       hash_map::Entry::Vacant(e) => { e.insert(vec![sp]); },
                                                                }
                                                        }
                                                }
@@ -2310,9 +2316,13 @@ fn walk_ast_first_pass<'a>(ast_storage: &'a FullLibraryAST, crate_types: &mut Cr
                                                        }
                                                        if let Some(tp) = import_resolver.maybe_resolve_path(&trait_path.1, None) {
                                                                if let Some(sp) = import_resolver.maybe_resolve_path(&p.path, None) {
-                                                                       match crate_types.trait_impls.entry(sp) {
-                                                                               hash_map::Entry::Occupied(mut e) => { e.get_mut().push(tp); },
-                                                                               hash_map::Entry::Vacant(e) => { e.insert(vec![tp]); },
+                                                                       match crate_types.trait_impls.entry(sp.clone()) {
+                                                                               hash_map::Entry::Occupied(mut e) => { e.get_mut().push(tp.clone()); },
+                                                                               hash_map::Entry::Vacant(e) => { e.insert(vec![tp.clone()]); },
+                                                                       }
+                                                                       match crate_types.traits_impld.entry(tp) {
+                                                                               hash_map::Entry::Occupied(mut e) => { e.get_mut().push(sp); },
+                                                                               hash_map::Entry::Vacant(e) => { e.insert(vec![sp]); },
                                                                        }
                                                                }
                                                        }