"bitcoin::secp256k1::Error" if !is_ref => Some("crate::c_types::Secp256k1Error"),
"bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice"),
"bitcoin::blockdata::script::Script" if !is_ref => Some("crate::c_types::derived::CVec_u8Z"),
"bitcoin::secp256k1::Error" if !is_ref => Some("crate::c_types::Secp256k1Error"),
"bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice"),
"bitcoin::blockdata::script::Script" if !is_ref => Some("crate::c_types::derived::CVec_u8Z"),
"bitcoin::blockdata::transaction::Transaction" => Some("crate::c_types::Transaction"),
"bitcoin::blockdata::transaction::TxOut" if !is_ref => Some("crate::c_types::TxOut"),
"bitcoin::blockdata::transaction::Transaction" => Some("crate::c_types::Transaction"),
"bitcoin::blockdata::transaction::TxOut" if !is_ref => Some("crate::c_types::TxOut"),
"bitcoin::network::constants::Network" => Some("crate::bitcoin::network::Network"),
"bitcoin::blockdata::block::BlockHeader" if is_ref => Some("*const [u8; 80]"),
"bitcoin::blockdata::block::Block" if is_ref => Some("crate::c_types::u8slice"),
"bitcoin::network::constants::Network" => Some("crate::bitcoin::network::Network"),
"bitcoin::blockdata::block::BlockHeader" if is_ref => Some("*const [u8; 80]"),
"bitcoin::blockdata::block::Block" if is_ref => Some("crate::c_types::u8slice"),
"bitcoin::hash_types::Txid" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
"bitcoin::hash_types::BlockHash" if is_ref => Some("*const [u8; 32]"),
"bitcoin::hash_types::BlockHash" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
"bitcoin::hash_types::Txid" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
"bitcoin::hash_types::BlockHash" if is_ref => Some("*const [u8; 32]"),
"bitcoin::hash_types::BlockHash" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
"ln::channelmanager::PaymentHash" if is_ref => Some("*const [u8; 32]"),
"ln::channelmanager::PaymentHash" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
"ln::channelmanager::PaymentPreimage" if is_ref => Some("*const [u8; 32]"),
"ln::channelmanager::PaymentHash" if is_ref => Some("*const [u8; 32]"),
"ln::channelmanager::PaymentHash" if !is_ref => Some("crate::c_types::ThirtyTwoBytes"),
"ln::channelmanager::PaymentPreimage" if is_ref => Some("*const [u8; 32]"),
// List of structs we map (possibly during processing of other files):
"ln::features::InitFeatures" if is_ref => Some(".inner) }"),
// List of structs we map (possibly during processing of other files):
"ln::features::InitFeatures" if is_ref => Some(".inner) }"),
// List of traits we map (possibly during processing of other files):
"crate::util::logger::Logger" => Some(""),
// List of traits we map (possibly during processing of other files):
"crate::util::logger::Logger" => Some(""),
"bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice::from_slice(&"),
"bitcoin::blockdata::script::Script" if !is_ref => Some(""),
"bitcoin::blockdata::transaction::Transaction" => Some("crate::c_types::Transaction::from_vec(local_"),
"bitcoin::blockdata::script::Script" if is_ref => Some("crate::c_types::u8slice::from_slice(&"),
"bitcoin::blockdata::script::Script" if !is_ref => Some(""),
"bitcoin::blockdata::transaction::Transaction" => Some("crate::c_types::Transaction::from_vec(local_"),
"bitcoin::blockdata::transaction::TxOut" if !is_ref => Some("crate::c_types::TxOut::from_rust("),
"bitcoin::blockdata::block::BlockHeader" if is_ref => Some("&local_"),
"bitcoin::blockdata::block::Block" if is_ref => Some("crate::c_types::u8slice::from_slice(&local_"),
"bitcoin::blockdata::transaction::TxOut" if !is_ref => Some("crate::c_types::TxOut::from_rust("),
"bitcoin::blockdata::block::BlockHeader" if is_ref => Some("&local_"),
"bitcoin::blockdata::block::Block" if is_ref => Some("crate::c_types::u8slice::from_slice(&local_"),
"bitcoin::hash_types::Txid" if is_ref => Some(""),
"bitcoin::hash_types::BlockHash" if is_ref => Some(""),
"bitcoin::hash_types::BlockHash" => Some("crate::c_types::ThirtyTwoBytes { data: "),
"bitcoin::hash_types::Txid" if is_ref => Some(""),
"bitcoin::hash_types::BlockHash" if is_ref => Some(""),
"bitcoin::hash_types::BlockHash" => Some("crate::c_types::ThirtyTwoBytes { data: "),
"ln::channelmanager::PaymentHash" if is_ref => Some("&"),
"ln::channelmanager::PaymentHash" if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "),
"ln::channelmanager::PaymentPreimage" if is_ref => Some("&"),
"ln::channelmanager::PaymentHash" if is_ref => Some("&"),
"ln::channelmanager::PaymentHash" if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "),
"ln::channelmanager::PaymentPreimage" if is_ref => Some("&"),
"bitcoin::blockdata::script::Script" if is_ref => Some("[..])"),
"bitcoin::blockdata::script::Script" if !is_ref => Some(".into_bytes().into()"),
"bitcoin::blockdata::transaction::Transaction" => Some(")"),
"bitcoin::blockdata::script::Script" if is_ref => Some("[..])"),
"bitcoin::blockdata::script::Script" if !is_ref => Some(".into_bytes().into()"),
"bitcoin::blockdata::transaction::Transaction" => Some(")"),
"bitcoin::blockdata::transaction::TxOut" if !is_ref => Some(")"),
"bitcoin::blockdata::block::BlockHeader" if is_ref => Some(""),
"bitcoin::blockdata::block::Block" if is_ref => Some(")"),
"bitcoin::blockdata::transaction::TxOut" if !is_ref => Some(")"),
"bitcoin::blockdata::block::BlockHeader" if is_ref => Some(""),
"bitcoin::blockdata::block::Block" if is_ref => Some(")"),
"bitcoin::hash_types::Txid" if is_ref => Some(".as_inner()"),
"bitcoin::hash_types::BlockHash" if is_ref => Some(".as_inner()"),
"bitcoin::hash_types::BlockHash" => Some(".into_inner() }"),
"bitcoin::hash_types::Txid" if is_ref => Some(".as_inner()"),
"bitcoin::hash_types::BlockHash" if is_ref => Some(".as_inner()"),
"bitcoin::hash_types::BlockHash" => Some(".into_inner() }"),
"ln::channelmanager::PaymentHash" if is_ref => Some(".0"),
"ln::channelmanager::PaymentHash" => Some(".0 }"),
"ln::channelmanager::PaymentPreimage" if is_ref => Some(".0"),
"ln::channelmanager::PaymentHash" if is_ref => Some(".0"),
"ln::channelmanager::PaymentHash" => Some(".0 }"),
"ln::channelmanager::PaymentPreimage" if is_ref => Some(".0"),
- vec![(".result_ok { true => Ok(".to_string(), format!("(*unsafe {{ Box::from_raw({}.contents.result.take_ptr()) }})", var_name)),
- ("), false => Err(".to_string(), format!("(*unsafe {{ Box::from_raw({}.contents.err.take_ptr()) }})", var_name))],
+ vec![(".result_ok { true => Ok(".to_string(), format!("(*unsafe {{ Box::from_raw(<*mut _>::take_ptr(&mut {}.contents.result)) }})", var_name)),
+ ("), false => Err(".to_string(), format!("(*unsafe {{ Box::from_raw(<*mut _>::take_ptr(&mut {}.contents.err)) }})", var_name))],
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);
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);
- 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!(); }
// 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!(); }
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::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(),
write!(w, ", is_owned: true }}").unwrap(),
DeclType::EnumIgnored|DeclType::StructImported if !is_ref => write!(w, ")), is_owned: true }}").unwrap(),
DeclType::Trait(_) if is_ref => {},
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<RustTypesImplementingTraits>
+ // we can just call .into() here and be done.
+ write!(w, ".into()").unwrap()
+ },
|w, decl_type, _full_path, is_ref, _is_mut| match decl_type {
DeclType::StructImported if is_ref && ptr_for_ref => write!(w, ").inner }}").unwrap(),
DeclType::StructImported if is_ref => write!(w, ".inner }}").unwrap(),
|w, decl_type, _full_path, is_ref, _is_mut| match decl_type {
DeclType::StructImported if is_ref && ptr_for_ref => write!(w, ").inner }}").unwrap(),
DeclType::StructImported if is_ref => write!(w, ".inner }}").unwrap(),
DeclType::MirroredEnum if is_ref => write!(w, ".to_native()").unwrap(),
DeclType::MirroredEnum => write!(w, ".into_native()").unwrap(),
DeclType::Trait(_) => {},
DeclType::MirroredEnum if is_ref => write!(w, ".to_native()").unwrap(),
DeclType::MirroredEnum => write!(w, ".into_native()").unwrap(),
DeclType::Trait(_) => {},
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_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();
}
} 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);
- fn write_template_generics<'b, W: std::io::Write>(&self, w: &mut W, args: &mut dyn Iterator<Item=&'b syn::Type>, is_ref: bool, in_crate: bool) {
+ fn write_template_generics<'b, W: std::io::Write>(&self, w: &mut W, args: &mut dyn Iterator<Item=&'b syn::Type>, generics: Option<&GenericTypes>, is_ref: bool, in_crate: bool) {
for (idx, t) in args.enumerate() {
if idx != 0 {
write!(w, ", ").unwrap();
for (idx, t) in args.enumerate() {
if idx != 0 {
write!(w, ", ").unwrap();
write!(w, "u8").unwrap();
} else {
write!(w, "{}::C{}TupleTempl<", Self::container_templ_path(), tup.elems.len()).unwrap();
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);
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) {
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) {
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!() }),
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!() }),
} 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!() }),
} 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!() }),
} else { unimplemented!(); }
} else if in_crate {
write!(w, "{}", c_type).unwrap();
} else {
} else { unimplemented!(); }
} else if in_crate {
write!(w, "{}", c_type).unwrap();
} else {
if self.crate_types.opaques.get(&resolved).is_some() {
write!(w, "crate::{}", resolved).unwrap();
} else {
if self.crate_types.opaques.get(&resolved).is_some() {
write!(w, "crate::{}", resolved).unwrap();
} else {
} else { unimplemented!(); }
} else if let syn::Type::Array(a_arg) = t {
if let syn::Type::Path(p_arg) = &*a_arg.elem {
} else { unimplemented!(); }
} else if let syn::Type::Array(a_arg) = t {
if let syn::Type::Path(p_arg) = &*a_arg.elem {
assert!(self.is_primitive(&resolved));
if let syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(len), .. }) = &a_arg.len {
write!(w, "{}",
assert!(self.is_primitive(&resolved));
if let syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(len), .. }) = &a_arg.len {
write!(w, "{}",
self.crate_types.templates_defined.insert(mangled_container.clone(), true);
let mut created_container: Vec<u8> = Vec::new();
self.crate_types.templates_defined.insert(mangled_container.clone(), true);
let mut created_container: Vec<u8> = Vec::new();
write!(&mut created_container, "{}::C{}Templ<", Self::container_templ_path(), container_type).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();
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);
writeln!(&mut created_container, ">;").unwrap();
self.write_template_constructor(&mut created_container, container_type, &mangled_container, &args, generics, is_ref);