X-Git-Url: http://git.bitcoin.ninja/index.cgi?p=ldk-c-bindings;a=blobdiff_plain;f=c-bindings-gen%2Fsrc%2Ftypes.rs;h=b0a410e208f01e9ff6f941234df862bbb4645c90;hp=2cb93690095247845687370e2011220b3dda945f;hb=c35ef17b94a8f4e9e019a2b63e0ed22110671b9c;hpb=6c95131720d1d390bf006f5160dcf4aa878fa4f0 diff --git a/c-bindings-gen/src/types.rs b/c-bindings-gen/src/types.rs index 2cb9369..b0a410e 100644 --- a/c-bindings-gen/src/types.rs +++ b/c-bindings-gen/src/types.rs @@ -15,6 +15,8 @@ use std::hash; use crate::blocks::*; use proc_macro2::{TokenTree, Span}; +use quote::format_ident; +use syn::parse_quote; // The following utils are used purely to build our known types maps - they break down all the // types we need to resolve to include the given object, and no more. @@ -341,11 +343,13 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr ($ident: expr, $path_suffix: expr) => { if partial_path == "" && !dependencies.contains(&$ident) { new_path = format!("{}::{}{}", crate_name, $ident, $path_suffix); - path.push(syn::PathSegment { ident: syn::Ident::new(crate_name, Span::call_site()), arguments: syn::PathArguments::None }); + let crate_name_ident = format_ident!("{}", crate_name); + path.push(parse_quote!(#crate_name_ident)); } else { new_path = format!("{}{}{}", partial_path, $ident, $path_suffix); } - path.push(syn::PathSegment { ident: $ident.clone(), arguments: syn::PathArguments::None }); + let ident = &$ident; + path.push(parse_quote!(#ident)); } } match u { @@ -383,10 +387,9 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr } fn insert_primitive(imports: &mut HashMap, id: &str) { - let ident = syn::Ident::new(id, Span::call_site()); - let mut path = syn::punctuated::Punctuated::new(); - path.push(syn::PathSegment { ident: ident.clone(), arguments: syn::PathArguments::None }); - imports.insert(ident, (id.to_owned(), syn::Path { leading_colon: None, segments: path })); + let ident = format_ident!("{}", id); + let path = parse_quote!(#ident); + imports.insert(ident, (id.to_owned(), path)); } pub fn new(crate_name: &'mod_lifetime str, dependencies: &'mod_lifetime HashSet, module_path: &'mod_lifetime str, contents: &'crate_lft [syn::Item]) -> Self { @@ -513,7 +516,10 @@ impl<'mod_lifetime, 'crate_lft: 'mod_lifetime> ImportResolver<'mod_lifetime, 'cr let remaining: String = seg_iter.map(|seg| { format!("::{}", seg.ident) }).collect(); - if let Some((imp, _)) = self.imports.get(&first_seg.ident) { + let first_seg_str = format!("{}", first_seg.ident); + if first_seg_str == "std" { + Some(first_seg_str + &remaining) + } else if let Some((imp, _)) = self.imports.get(&first_seg.ident) { if remaining != "" { Some(imp.clone() + &remaining) } else { @@ -775,11 +781,15 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "String" if is_ref => Some("crate::c_types::Str"), "std::time::Duration" => Some("u64"), + "std::io::Error" => Some("crate::c_types::IOError"), - "bitcoin::secp256k1::key::PublicKey" => Some("crate::c_types::PublicKey"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some("crate::c_types::PublicKey"), "bitcoin::secp256k1::Signature" => Some("crate::c_types::Signature"), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some("*const [u8; 32]"), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some("crate::c_types::SecretKey"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some("*const [u8; 32]"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some("crate::c_types::SecretKey"), "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"), @@ -840,12 +850,16 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some("std::time::Duration::from_secs("), - "bitcoin::secp256k1::key::PublicKey" if is_ref => Some("&"), - "bitcoin::secp256k1::key::PublicKey" => Some(""), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + if is_ref => Some("&"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some(""), "bitcoin::secp256k1::Signature" if is_ref => Some("&"), "bitcoin::secp256k1::Signature" => Some(""), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some("&::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *"), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some(""), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some("&::bitcoin::secp256k1::key::SecretKey::from_slice(&unsafe { *"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some(""), "bitcoin::blockdata::script::Script" if is_ref => Some("&::bitcoin::blockdata::script::Script::from(Vec::from("), "bitcoin::blockdata::script::Script" if !is_ref => Some("::bitcoin::blockdata::script::Script::from("), "bitcoin::blockdata::transaction::Transaction" if is_ref => Some("&"), @@ -895,10 +909,13 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "std::time::Duration" => Some(")"), - "bitcoin::secp256k1::key::PublicKey" => Some(".into_rust()"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some(".into_rust()"), "bitcoin::secp256k1::Signature" => Some(".into_rust()"), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some(".into_rust()"), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some("}[..]).unwrap()"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some(".into_rust()"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some("}[..]).unwrap()"), "bitcoin::blockdata::script::Script" if is_ref => Some(".to_slice()))"), "bitcoin::blockdata::script::Script" if !is_ref => Some(".into_rust())"), "bitcoin::blockdata::transaction::Transaction" => Some(".into_bitcoin()"), @@ -932,8 +949,6 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "[u8]" if is_ref => Some(("crate::c_types::u8slice::from_slice(", ")")), "[usize]" if is_ref => Some(("crate::c_types::usizeslice::from_slice(", ")")), - "bitcoin::blockdata::transaction::Transaction" if is_ref => Some(("::bitcoin::consensus::encode::serialize(", ")")), - "bitcoin::blockdata::transaction::Transaction" if !is_ref => Some(("::bitcoin::consensus::encode::serialize(&", ")")), "bitcoin::blockdata::block::BlockHeader" if is_ref => Some(("{ let mut s = [0u8; 80]; s[..].copy_from_slice(&::bitcoin::consensus::encode::serialize(", ")); s }")), "bitcoin::blockdata::block::Block" if is_ref => Some(("::bitcoin::consensus::encode::serialize(", ")")), "bitcoin::hash_types::Txid" => None, @@ -954,11 +969,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "Option" => Some("local_"), "[u8; 32]" if !is_ref => Some("crate::c_types::ThirtyTwoBytes { data: "), - "[u8; 32]" if is_ref => Some("&"), + "[u8; 32]" if is_ref => Some(""), "[u8; 16]" if !is_ref => Some("crate::c_types::SixteenBytes { data: "), "[u8; 10]" if !is_ref => Some("crate::c_types::TenBytes { data: "), "[u8; 4]" if !is_ref => Some("crate::c_types::FourBytes { data: "), - "[u8; 3]" if is_ref => Some("&"), + "[u8; 3]" if is_ref => Some(""), "[u8]" if is_ref => Some("local_"), "[usize]" if is_ref => Some("local_"), @@ -967,15 +982,20 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "String" => Some(""), "std::time::Duration" => Some(""), + "std::io::Error" if !is_ref => Some("crate::c_types::IOError::from_rust("), - "bitcoin::secp256k1::key::PublicKey" => Some("crate::c_types::PublicKey::from_rust(&"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some("crate::c_types::PublicKey::from_rust(&"), "bitcoin::secp256k1::Signature" => Some("crate::c_types::Signature::from_rust(&"), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some(""), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some("crate::c_types::SecretKey::from_rust("), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some(""), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some("crate::c_types::SecretKey::from_rust("), "bitcoin::secp256k1::Error" if !is_ref => Some("crate::c_types::Secp256k1Error::from_rust("), "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::Transaction" if is_ref => Some("crate::c_types::Transaction::from_bitcoin("), + "bitcoin::blockdata::transaction::Transaction" => Some("crate::c_types::Transaction::from_bitcoin(&"), "bitcoin::blockdata::transaction::OutPoint" => Some("crate::c_types::bitcoin_to_C_outpoint("), "bitcoin::blockdata::transaction::TxOut" if !is_ref => Some("crate::c_types::TxOut::from_rust("), "bitcoin::network::constants::Network" => Some("crate::bitcoin::network::Network::from_bitcoin("), @@ -1025,11 +1045,15 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { "String" if is_ref => Some(".as_str().into()"), "std::time::Duration" => Some(".as_secs()"), + "std::io::Error" if !is_ref => Some(")"), - "bitcoin::secp256k1::key::PublicKey" => Some(")"), + "bitcoin::secp256k1::key::PublicKey"|"bitcoin::secp256k1::PublicKey" + => Some(")"), "bitcoin::secp256k1::Signature" => Some(")"), - "bitcoin::secp256k1::key::SecretKey" if !is_ref => Some(")"), - "bitcoin::secp256k1::key::SecretKey" if is_ref => Some(".as_ref()"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if !is_ref => Some(")"), + "bitcoin::secp256k1::key::SecretKey"|"bitcoin::secp256k1::SecretKey" + if is_ref => Some(".as_ref()"), "bitcoin::secp256k1::Error" if !is_ref => Some(")"), "bitcoin::blockdata::script::Script" if is_ref => Some("[..])"), "bitcoin::blockdata::script::Script" if !is_ref => Some(".into_bytes().into()"), @@ -1135,7 +1159,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { Some(("Vec::new(); for mut item in ", vec![(format!(".drain(..) {{ local_{}.push(", var_name), "item".to_string())], "); }", ContainerPrefixLocation::PerConv)) }, "Slice" => { - Some(("Vec::new(); for item in ", vec![(format!(".iter() {{ local_{}.push(", var_name), "**item".to_string())], "); }", ContainerPrefixLocation::PerConv)) + Some(("Vec::new(); for item in ", vec![(format!(".iter() {{ local_{}.push(", var_name), "*item".to_string())], "); }", ContainerPrefixLocation::PerConv)) }, "Option" => { if let Some(syn::Type::Path(p)) = single_contained { @@ -1434,16 +1458,8 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { split.next().unwrap(); let tail_str = split.next().unwrap(); assert!(split.next().is_none()); - let len = &tail_str[..tail_str.len() - 1]; - Some(syn::Type::Array(syn::TypeArray { - bracket_token: syn::token::Bracket { span: Span::call_site() }, - elem: Box::new(syn::Type::Path(syn::TypePath { - qself: None, - path: syn::Path::from(syn::PathSegment::from(syn::Ident::new("u8", Span::call_site()))), - })), - semi_token: syn::Token!(;)(Span::call_site()), - len: syn::Expr::Lit(syn::ExprLit { attrs: Vec::new(), lit: syn::Lit::Int(syn::LitInt::new(len, Span::call_site())) }), - })) + let len = usize::from_str_radix(&tail_str[..tail_str.len() - 1], 10).unwrap(); + Some(parse_quote!([u8; #len])) } else { None } } else { None } } @@ -1550,7 +1566,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } fn write_conversion_inline_intern Option, DL: Fn(&mut W, &DeclType, &str, bool, bool), SC: Fn(bool) -> &'static str> + LP: Fn(&str, bool, bool) -> Option, DL: Fn(&mut W, &DeclType, &str, bool, bool), SC: Fn(bool, Option<&str>) -> String> (&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, is_mut: bool, ptr_for_ref: bool, tupleconv: &str, prefix: bool, sliceconv: SC, path_lookup: LP, decl_lookup: DL) { match t { @@ -1566,6 +1582,10 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { let resolved_path = self.resolve_path(&p.path, generics); if let Some(aliased_type) = self.crate_types.type_aliases.get(&resolved_path) { return self.write_conversion_inline_intern(w, aliased_type, None, is_ref, is_mut, ptr_for_ref, tupleconv, prefix, sliceconv, path_lookup, decl_lookup); + } else if self.is_primitive(&resolved_path) { + if is_ref && prefix { + write!(w, "*").unwrap(); + } } else if let Some(c_type) = path_lookup(&resolved_path, is_ref, ptr_for_ref) { write!(w, "{}", c_type).unwrap(); } else if self.crate_types.opaques.get(&resolved_path).is_some() { @@ -1598,12 +1618,12 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { write!(w, "{}", path_lookup("[u8]", is_ref, ptr_for_ref).unwrap()).unwrap(); } else if let syn::Type::Reference(r) = &*s.elem { if let syn::Type::Path(p) = &*r.elem { - write!(w, "{}", sliceconv(self.c_type_has_inner_from_path(&self.resolve_path(&p.path, generics)))).unwrap(); + write!(w, "{}", sliceconv(self.c_type_has_inner_from_path(&self.resolve_path(&p.path, generics)), None)).unwrap(); } else { unimplemented!(); } } else if let syn::Type::Tuple(t) = &*s.elem { assert!(!t.elems.is_empty()); if prefix { - write!(w, "&local_").unwrap(); + write!(w, "{}", sliceconv(false, None)).unwrap(); } else { let mut needs_map = false; for e in t.elems.iter() { @@ -1612,19 +1632,23 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } } if needs_map { - write!(w, ".iter().map(|(").unwrap(); + let mut map_str = Vec::new(); + write!(&mut map_str, ".map(|(").unwrap(); for i in 0..t.elems.len() { - write!(w, "{}{}", if i != 0 { ", " } else { "" }, ('a' as u8 + i as u8) as char).unwrap(); + write!(&mut map_str, "{}{}", if i != 0 { ", " } else { "" }, ('a' as u8 + i as u8) as char).unwrap(); } - write!(w, ")| (").unwrap(); + write!(&mut map_str, ")| (").unwrap(); for (idx, e) in t.elems.iter().enumerate() { if let syn::Type::Reference(_) = e { - write!(w, "{}{}", if idx != 0 { ", " } else { "" }, (idx as u8 + 'a' as u8) as char).unwrap(); + write!(&mut map_str, "{}{}", if idx != 0 { ", " } else { "" }, (idx as u8 + 'a' as u8) as char).unwrap(); } else if let syn::Type::Path(_) = e { - write!(w, "{}*{}", if idx != 0 { ", " } else { "" }, (idx as u8 + 'a' as u8) as char).unwrap(); + write!(&mut map_str, "{}*{}", if idx != 0 { ", " } else { "" }, (idx as u8 + 'a' as u8) as char).unwrap(); } else { unimplemented!(); } } - write!(w, ")).collect::>()[..]").unwrap(); + write!(&mut map_str, "))").unwrap(); + write!(w, "{}", sliceconv(false, Some(&String::from_utf8(map_str).unwrap()))).unwrap(); + } else { + write!(w, "{}", sliceconv(false, None)).unwrap(); } } } else { unimplemented!(); } @@ -1643,24 +1667,24 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } fn write_to_c_conversion_inline_prefix_inner(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, ptr_for_ref: bool, from_ptr: bool) { - self.write_conversion_inline_intern(w, t, generics, is_ref, false, ptr_for_ref, "0u8 /*", true, |_| "local_", + self.write_conversion_inline_intern(w, t, generics, is_ref, false, ptr_for_ref, "0u8 /*", true, |_, _| "local_".to_owned(), |a, b, c| self.to_c_conversion_inline_prefix_from_path(a, b, c), |w, decl_type, decl_path, is_ref, _is_mut| { match decl_type { - DeclType::MirroredEnum if is_ref && ptr_for_ref => write!(w, "crate::{}::from_native(&", decl_path).unwrap(), - DeclType::MirroredEnum if is_ref => write!(w, "&crate::{}::from_native(&", decl_path).unwrap(), + DeclType::MirroredEnum if is_ref && ptr_for_ref => write!(w, "crate::{}::from_native(", decl_path).unwrap(), + DeclType::MirroredEnum if is_ref => write!(w, "&crate::{}::from_native(", decl_path).unwrap(), DeclType::MirroredEnum => write!(w, "crate::{}::native_into(", decl_path).unwrap(), DeclType::EnumIgnored|DeclType::StructImported if is_ref && ptr_for_ref && from_ptr => write!(w, "crate::{} {{ inner: unsafe {{ (", decl_path).unwrap(), DeclType::EnumIgnored|DeclType::StructImported if is_ref && ptr_for_ref => - write!(w, "crate::{} {{ inner: unsafe {{ ( (&(", decl_path).unwrap(), + write!(w, "crate::{} {{ inner: unsafe {{ ( (&(*", decl_path).unwrap(), DeclType::EnumIgnored|DeclType::StructImported if is_ref => write!(w, "&crate::{} {{ inner: unsafe {{ (", decl_path).unwrap(), DeclType::EnumIgnored|DeclType::StructImported if !is_ref && from_ptr => write!(w, "crate::{} {{ inner: ", decl_path).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(), + DeclType::Trait(_) if is_ref => write!(w, "").unwrap(), DeclType::Trait(_) if !is_ref => {}, _ => panic!("{:?}", decl_path), } @@ -1670,7 +1694,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { self.write_to_c_conversion_inline_prefix_inner(w, t, generics, false, ptr_for_ref, false); } fn write_to_c_conversion_inline_suffix_inner(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, ptr_for_ref: bool, from_ptr: bool) { - self.write_conversion_inline_intern(w, t, generics, is_ref, false, ptr_for_ref, "*/", false, |_| ".into()", + self.write_conversion_inline_intern(w, t, generics, is_ref, false, ptr_for_ref, "*/", false, |_, _| ".into()".to_owned(), |a, b, c| self.to_c_conversion_inline_suffix_from_path(a, b, c), |w, decl_type, _full_path, is_ref, _is_mut| match decl_type { DeclType::MirroredEnum => write!(w, ")").unwrap(), @@ -1699,7 +1723,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } fn write_from_c_conversion_prefix_inner(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, ptr_for_ref: bool) { - self.write_conversion_inline_intern(w, t, generics, is_ref, false, false, "() /*", true, |_| "&local_", + self.write_conversion_inline_intern(w, t, generics, is_ref, false, false, "() /*", true, |_, _| "&local_".to_owned(), |a, b, _c| self.from_c_conversion_prefix_from_path(a, b), |w, decl_type, _full_path, is_ref, is_mut| match decl_type { DeclType::StructImported if is_ref && ptr_for_ref => write!(w, "unsafe {{ &*(*").unwrap(), @@ -1717,9 +1741,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } fn write_from_c_conversion_suffix_inner(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>, is_ref: bool, ptr_for_ref: bool) { self.write_conversion_inline_intern(w, t, generics, is_ref, false, false, "*/", false, - |has_inner| match has_inner { - false => ".iter().collect::>()[..]", - true => "[..]", + |has_inner, map_str_opt| match (has_inner, map_str_opt) { + (false, Some(map_str)) => format!(".iter(){}.collect::>()[..]", map_str), + (false, None) => ".iter().collect::>()[..]".to_owned(), + (true, None) => "[..]".to_owned(), + (true, Some(_)) => unreachable!(), }, |a, b, _c| self.from_c_conversion_suffix_from_path(a, b), |w, decl_type, _full_path, is_ref, _is_mut| match decl_type { @@ -1738,7 +1764,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { // Note that compared to the above conversion functions, the following two are generally // significantly undertested: pub fn write_from_c_conversion_to_ref_prefix(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>) { - self.write_conversion_inline_intern(w, t, generics, false, false, false, "() /*", true, |_| "&local_", + self.write_conversion_inline_intern(w, t, generics, false, false, false, "() /*", true, |_, _| "&local_".to_owned(), |a, b, _c| { if let Some(conv) = self.from_c_conversion_prefix_from_path(a, b) { Some(format!("&{}", conv)) @@ -1751,9 +1777,11 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { } pub fn write_from_c_conversion_to_ref_suffix(&self, w: &mut W, t: &syn::Type, generics: Option<&GenericTypes>) { self.write_conversion_inline_intern(w, t, generics, false, false, false, "*/", false, - |has_inner| match has_inner { - false => ".iter().collect::>()[..]", - true => "[..]", + |has_inner, map_str_opt| match (has_inner, map_str_opt) { + (false, Some(map_str)) => format!(".iter(){}.collect::>()[..]", map_str), + (false, None) => ".iter().collect::>()[..]".to_owned(), + (true, None) => "[..]".to_owned(), + (true, Some(_)) => unreachable!(), }, |a, b, _c| self.from_c_conversion_suffix_from_path(a, b), |w, decl_type, _full_path, is_ref, _is_mut| match decl_type { @@ -1836,7 +1864,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { write!(w, "{} {{ ", pfx).unwrap(); let new_var_name = format!("{}_{}", ident, idx); - let new_var = self.write_conversion_new_var_intern(w, &syn::Ident::new(&new_var_name, Span::call_site()), + let new_var = self.write_conversion_new_var_intern(w, &format_ident!("{}", new_var_name), &var_access, conv_ty, generics, contains_slice || (is_ref && ty_has_inner), ptr_for_ref, to_c, path_lookup, container_lookup, var_prefix, var_suffix); if new_var { write!(w, " ").unwrap(); } @@ -1961,7 +1989,7 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { for (idx, elem) in t.elems.iter().enumerate() { if let syn::Type::Path(p) = elem { let v_name = format!("orig_{}_{}", ident, idx); - let tuple_elem_ident = syn::Ident::new(&v_name, Span::call_site()); + let tuple_elem_ident = format_ident!("{}", &v_name); if self.write_conversion_new_var_intern(w, &tuple_elem_ident, &v_name, elem, generics, false, ptr_for_ref, to_c, path_lookup, container_lookup, var_prefix, var_suffix) { @@ -2375,15 +2403,10 @@ impl<'a, 'c: 'a> TypeResolver<'a, 'c> { self.check_create_container(mangled_container, "Vec", vec![&*r.elem], generics, false) } else { false } } else if let syn::Type::Tuple(_) = &*s.elem { - let mut args = syn::punctuated::Punctuated::new(); + let mut args = syn::punctuated::Punctuated::<_, syn::token::Comma>::new(); args.push(syn::GenericArgument::Type((*s.elem).clone())); let mut segments = syn::punctuated::Punctuated::new(); - segments.push(syn::PathSegment { - ident: syn::Ident::new("Vec", Span::call_site()), - arguments: syn::PathArguments::AngleBracketed(syn::AngleBracketedGenericArguments { - colon2_token: None, lt_token: syn::Token![<](Span::call_site()), args, gt_token: syn::Token![>](Span::call_site()), - }) - }); + segments.push(parse_quote!(Vec<#args>)); self.write_c_type_intern(w, &syn::Type::Path(syn::TypePath { qself: None, path: syn::Path { leading_colon: None, segments } }), generics, false, is_mut, ptr_for_ref) } else { false } },