X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=c-bindings-gen%2Fsrc%2Ftypes.rs;h=0a320f3872be9e12d3ded19a83d4855e49387491;hb=c3d52f5f16d850662ab046a8eaf6cda9a3e40a72;hp=935e572ca4aaeeead2f87b6c2932b1676891c9a7;hpb=f2d042290822344064a964b8ddce77525fd4d1b4;p=rust-lightning diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index 935e572ca..0a320f387 100644 --- a/c-bindings-gen/src/types.rs +++ b/c-bindings-gen/src/types.rs @@ -1242,17 +1242,16 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { decl_lookup(w, &DeclType::StructImported, &resolved_path, is_ref, is_mut); } else if self.crate_types.mirrored_enums.get(&resolved_path).is_some() { decl_lookup(w, &DeclType::MirroredEnum, &resolved_path, is_ref, is_mut); + } else if let Some(t) = self.crate_types.traits.get(&resolved_path) { + decl_lookup(w, &DeclType::Trait(t), &resolved_path, is_ref, is_mut); } else if let Some(ident) = single_ident_generic_path_to_ident(&p.path) { - if let Some(t) = self.crate_types.traits.get(&resolved_path) { - decl_lookup(w, &DeclType::Trait(t), &resolved_path, is_ref, is_mut); - return; - } else if let Some(_) = self.imports.get(ident) { + if let Some(_) = self.imports.get(ident) { // crate_types lookup has to have succeeded: panic!("Failed to print inline conversion for {}", ident); } else if let Some(decl_type) = self.declared.get(ident) { decl_lookup(w, decl_type, &self.maybe_resolve_ident(ident).unwrap(), is_ref, is_mut); } else { unimplemented!(); } - } + } else { unimplemented!(); } }, syn::Type::Array(a) => { // We assume all arrays contain only [int_literal; X]s. @@ -1335,6 +1334,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { DeclType::EnumIgnored|DeclType::StructImported if !is_ref => write!(w, "crate::{} {{ inner: Box::into_raw(Box::new(", decl_path).unwrap(), DeclType::Trait(_) if is_ref => write!(w, "&").unwrap(), + DeclType::Trait(_) if !is_ref => {}, _ => panic!("{:?}", decl_path), } }); @@ -1357,6 +1357,13 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { write!(w, ", is_owned: true }}").unwrap(), DeclType::EnumIgnored|DeclType::StructImported if !is_ref => write!(w, ")), is_owned: true }}").unwrap(), DeclType::Trait(_) if is_ref => {}, + DeclType::Trait(_) => { + // This is used when we're converting a concrete Rust type into a C trait + // for use when a Rust trait method returns an associated type. + // Because all of our C traits implement From + // we can just call .into() here and be done. + write!(w, ".into()").unwrap() + }, _ => unimplemented!(), }); } @@ -1719,14 +1726,14 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { self.write_c_mangled_container_path_intern(w, Self::path_to_generic_args(path), generics, &format!("{}", single_ident_generic_path_to_ident(path).unwrap()), is_ref, false, false, false); } else { - self.write_template_generics(w, &mut [$item].iter().map(|t| *t), is_ref, true); + self.write_template_generics(w, &mut [$item].iter().map(|t| *t), generics, is_ref, true); } } else if let syn::Type::Tuple(syn::TypeTuple { elems, .. }) = $item { self.write_c_mangled_container_path_intern(w, elems.iter().collect(), generics, &format!("{}Tuple", elems.len()), is_ref, false, false, false); } else { unimplemented!(); } write!(w, ") -> {} =\n\t{}::CResultTempl::<", mangled_container, Self::container_templ_path()).unwrap(); - self.write_template_generics(w, &mut args.iter().map(|t| *t), is_ref, true); + self.write_template_generics(w, &mut args.iter().map(|t| *t), generics, is_ref, true); writeln!(w, ">::{};\n", $call).unwrap(); } } } @@ -1755,7 +1762,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } } - fn write_template_generics<'b, W: std::io::Write>(&self, w: &mut W, args: &mut dyn Iterator, is_ref: bool, in_crate: bool) { + fn write_template_generics<'b, W: std::io::Write>(&self, w: &mut W, args: &mut dyn Iterator, generics: Option<&GenericTypes>, is_ref: bool, in_crate: bool) { for (idx, t) in args.enumerate() { if idx != 0 { write!(w, ", ").unwrap(); @@ -1765,11 +1772,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { write!(w, "u8").unwrap(); } else { write!(w, "{}::C{}TupleTempl<", Self::container_templ_path(), tup.elems.len()).unwrap(); - self.write_template_generics(w, &mut tup.elems.iter(), is_ref, in_crate); + self.write_template_generics(w, &mut tup.elems.iter(), generics, is_ref, in_crate); write!(w, ">").unwrap(); } } else if let syn::Type::Path(p_arg) = t { - let resolved_generic = self.resolve_path(&p_arg.path, None); + let resolved_generic = self.resolve_path(&p_arg.path, generics); if self.is_primitive(&resolved_generic) { write!(w, "{}", resolved_generic).unwrap(); } else if let Some(c_type) = self.c_type_from_path(&resolved_generic, is_ref, false) { @@ -1779,19 +1786,19 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { if let syn::PathArguments::AngleBracketed(args) = &p_arg.path.segments.iter().next().unwrap().arguments { self.write_template_generics(w, &mut args.args.iter().map(|gen| if let syn::GenericArgument::Type(t) = gen { t } else { unimplemented!() }), - is_ref, in_crate); + generics, is_ref, in_crate); } else { unimplemented!(); } write!(w, ">").unwrap(); } else if resolved_generic == "Option" { if let syn::PathArguments::AngleBracketed(args) = &p_arg.path.segments.iter().next().unwrap().arguments { self.write_template_generics(w, &mut args.args.iter().map(|gen| if let syn::GenericArgument::Type(t) = gen { t } else { unimplemented!() }), - is_ref, in_crate); + generics, is_ref, in_crate); } else { unimplemented!(); } } else if in_crate { write!(w, "{}", c_type).unwrap(); } else { - self.write_rust_type(w, None, &t); + self.write_rust_type(w, generics, &t); } } else { // If we just write out resolved_generic, it may mostly work, however for @@ -1811,7 +1818,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } } else if let syn::Type::Reference(r_arg) = t { if let syn::Type::Path(p_arg) = &*r_arg.elem { - let resolved = self.resolve_path(&p_arg.path, None); + let resolved = self.resolve_path(&p_arg.path, generics); if self.crate_types.opaques.get(&resolved).is_some() { write!(w, "crate::{}", resolved).unwrap(); } else { @@ -1821,7 +1828,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } else { unimplemented!(); } } else if let syn::Type::Array(a_arg) = t { if let syn::Type::Path(p_arg) = &*a_arg.elem { - let resolved = self.resolve_path(&p_arg.path, None); + let resolved = self.resolve_path(&p_arg.path, generics); assert!(self.is_primitive(&resolved)); if let syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(len), .. }) = &a_arg.len { write!(w, "{}", @@ -1838,12 +1845,12 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { write!(&mut created_container, "#[no_mangle]\npub type {} = ", mangled_container).unwrap(); write!(&mut created_container, "{}::C{}Templ<", Self::container_templ_path(), container_type).unwrap(); - self.write_template_generics(&mut created_container, &mut args.iter().map(|t| *t), is_ref, true); + self.write_template_generics(&mut created_container, &mut args.iter().map(|t| *t), generics, is_ref, true); writeln!(&mut created_container, ">;").unwrap(); write!(&mut created_container, "#[no_mangle]\npub static {}_free: extern \"C\" fn({}) = ", mangled_container, mangled_container).unwrap(); write!(&mut created_container, "{}::C{}Templ_free::<", Self::container_templ_path(), container_type).unwrap(); - self.write_template_generics(&mut created_container, &mut args.iter().map(|t| *t), is_ref, true); + self.write_template_generics(&mut created_container, &mut args.iter().map(|t| *t), generics, is_ref, true); writeln!(&mut created_container, ">;").unwrap(); self.write_template_constructor(&mut created_container, container_type, &mangled_container, &args, generics, is_ref);