X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=c-bindings-gen%2Fsrc%2Ftypes.rs;h=9df1bd1c1ef309e13aef79f99072c3c265adf128;hb=3398c19e2889fbe22590d8991b4ce1bc176ec1bc;hp=6d97ccc32ffb10357bf020c2eefe8c56bea01b78;hpb=3ddf30cda74b64d1e1fe3f57e06cbb5440f630e4;p=ldk-c-bindings diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index 6d97ccc..9df1bd1 100644 --- a/c-bindings-gen/src/types.rs +++ b/c-bindings-gen/src/types.rs @@ -225,7 +225,8 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { if path == "Sized" { continue; } if non_lifetimes_processed { return false; } non_lifetimes_processed = true; - if path != "std::ops::Deref" && path != "core::ops::Deref" { + if path != "std::ops::Deref" && path != "core::ops::Deref" && + path != "std::ops::DerefMut" && path != "core::ops::DerefMut" { let p = string_path_to_syn_path(&path); let ref_ty = parse_quote!(&#p); let mut_ref_ty = parse_quote!(&mut #p); @@ -347,8 +348,24 @@ impl<'a, 'p: 'a> GenericTypes<'a, 'p> { // implement Deref 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" { + if path != "std::ops::Deref" && path != "core::ops::Deref" && + path != "std::ops::DerefMut" && path != "core::ops::DerefMut" { self.typed_generics.insert(&t.ident, path); + } else { + let last_seg_args = &tr.path.segments.last().unwrap().arguments; + if let syn::PathArguments::AngleBracketed(args) = last_seg_args { + assert_eq!(args.args.len(), 1); + if let syn::GenericArgument::Binding(binding) = &args.args[0] { + assert_eq!(format!("{}", binding.ident), "Target"); + if let syn::Type::Path(p) = &binding.ty { + // Note that we are assuming the order of type + // declarations here, but that should be easy + // to handle. + let real_path = self.maybe_resolve_path(&p.path).unwrap(); + self.typed_generics.insert(&t.ident, real_path.clone()); + } else { unimplemented!(); } + } else { unimplemented!(); } + } else { unimplemented!(); } } } else { unimplemented!(); } for bound in bounds_iter { @@ -548,6 +565,7 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr Self::insert_primitive(&mut imports, "bool"); Self::insert_primitive(&mut imports, "u128"); Self::insert_primitive(&mut imports, "i64"); + Self::insert_primitive(&mut imports, "f64"); Self::insert_primitive(&mut imports, "u64"); Self::insert_primitive(&mut imports, "u32"); Self::insert_primitive(&mut imports, "u16"); @@ -667,6 +685,33 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr pub fn maybe_resolve_path(&self, p: &syn::Path, generics: Option<&GenericTypes>) -> Option { self.maybe_resolve_imported_path(p, generics).map(|mut path| { + if path == "core::ops::Deref" || path == "core::ops::DerefMut" { + let last_seg = p.segments.last().unwrap(); + if let syn::PathArguments::AngleBracketed(args) = &last_seg.arguments { + assert_eq!(args.args.len(), 1); + if let syn::GenericArgument::Binding(binding) = &args.args[0] { + if let syn::Type::Path(p) = &binding.ty { + if let Some(inner_ty) = self.maybe_resolve_path(&p.path, generics) { + let mut module_riter = inner_ty.rsplitn(2, "::"); + let ty_ident = module_riter.next().unwrap(); + let module_name = module_riter.next().unwrap(); + let module = self.library.modules.get(module_name).unwrap(); + for item in module.items.iter() { + match item { + syn::Item::Trait(t) => { + if t.ident == ty_ident { + path = inner_ty; + break; + } + }, + _ => {} + } + } + } + } else { unimplemented!(); } + } else { unimplemented!(); } + } + } loop { // Now that we've resolved the path to the path as-imported, check whether the path // is actually a pub(.*) use statement and map it to the real path. @@ -950,6 +995,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { match full_path { "bool" => true, "i64" => true, + "f64" => true, "u64" => true, "u32" => true, "u16" => true, @@ -2854,7 +2900,14 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { generics, &subtype, is_ref, is_mut, ptr_for_ref, true); } } else { - let id = subtype.rsplitn(2, ':').next().unwrap(); // Get the "Base" name of the resolved type + let mut resolved = Vec::new(); + let id = + if self.write_c_path_intern(&mut resolved, &$p_arg.path, generics, false, false, false, false, false) { + let inner = std::str::from_utf8(&resolved).unwrap(); + inner.rsplitn(2, "::").next().unwrap() + } else { + subtype.rsplitn(2, "::").next().unwrap() + }; write!(w, "{}", id).unwrap(); write!(mangled_type, "{}", id).unwrap(); if let Some(w2) = $extra_write as Option<&mut Vec> { @@ -2888,9 +2941,9 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } else { return false; } } else if let syn::Type::Array(_) = elem { let mut resolved = Vec::new(); - if !self.write_c_type_intern(&mut resolved, &elem, generics, false, false, true, false, true) { return false; } + if !self.write_c_type_intern(&mut resolved, &elem, generics, false, false, false, false, false) { return false; } let array_inner = String::from_utf8(resolved).unwrap(); - let arr_name = array_inner.split("::").last().unwrap(); + let arr_name = array_inner.rsplitn(2, "::").next().unwrap(); write!(w, "{}", arr_name).unwrap(); write!(mangled_type, "{}", arr_name).unwrap(); } else { return false; }