Track independent Rust/C++ names on struct fields and fn args

This commit is contained in:
David Tolnay 2021-01-01 15:30:14 -08:00
parent b97a245c93
commit 84ed6adda5
No known key found for this signature in database
GPG Key ID: F9BA143B95FF6D82
9 changed files with 50 additions and 52 deletions

View File

@ -240,7 +240,7 @@ fn write_struct<'a>(out: &mut OutFile<'a>, strct: &'a Struct, methods: &[&Extern
}
write!(out, " ");
write_type_space(out, &field.ty);
writeln!(out, "{};", field.ident);
writeln!(out, "{};", field.name.cxx);
}
writeln!(out);
@ -755,28 +755,28 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
}
if let Type::RustBox(_) = &arg.ty {
write_type(out, &arg.ty);
write!(out, "::from_raw({})", arg.ident);
write!(out, "::from_raw({})", arg.name.cxx);
} else if let Type::UniquePtr(_) = &arg.ty {
write_type(out, &arg.ty);
write!(out, "({})", arg.ident);
write!(out, "({})", arg.name.cxx);
} else if let Type::Str(_) = arg.ty {
out.builtin.rust_str_new_unchecked = true;
write!(
out,
"::rust::impl<::rust::Str>::new_unchecked({})",
arg.ident,
arg.name.cxx,
);
} else if arg.ty == RustString {
out.builtin.unsafe_bitcopy = true;
write!(
out,
"::rust::String(::rust::unsafe_bitcopy, *{})",
arg.ident,
arg.name.cxx,
);
} else if let Type::RustVec(_) = arg.ty {
out.builtin.unsafe_bitcopy = true;
write_type(out, &arg.ty);
write!(out, "(::rust::unsafe_bitcopy, *{})", arg.ident);
write!(out, "(::rust::unsafe_bitcopy, *{})", arg.name.cxx);
} else if let Type::SliceRef(slice) = &arg.ty {
write_type(out, &arg.ty);
write!(out, "(static_cast<");
@ -784,12 +784,12 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
write!(out, "const ");
}
write_type_space(out, &slice.inner);
write!(out, "*>({0}.ptr), {0}.len)", arg.ident);
write!(out, "*>({0}.ptr), {0}.len)", arg.name.cxx);
} else if out.types.needs_indirect_abi(&arg.ty) {
out.include.utility = true;
write!(out, "::std::move(*{})", arg.ident);
write!(out, "::std::move(*{})", arg.name.cxx);
} else {
write!(out, "{}", arg.ident);
write!(out, "{}", arg.name.cxx);
}
}
write!(out, ")");
@ -820,19 +820,14 @@ fn write_cxx_function_shim<'a>(out: &mut OutFile<'a>, efn: &'a ExternFn) {
writeln!(out, "}}");
for arg in &efn.args {
if let Type::Fn(f) = &arg.ty {
let var = &arg.ident;
let var = &arg.name;
write_function_pointer_trampoline(out, efn, var, f);
}
}
out.end_block(Block::ExternC);
}
fn write_function_pointer_trampoline(
out: &mut OutFile,
efn: &ExternFn,
var: &Ident,
f: &Signature,
) {
fn write_function_pointer_trampoline(out: &mut OutFile, efn: &ExternFn, var: &Pair, f: &Signature) {
let r_trampoline = mangle::r_trampoline(efn, var, out.types);
let indirect_call = true;
write_rust_function_decl_impl(out, &r_trampoline, f, indirect_call);
@ -928,7 +923,7 @@ fn write_rust_function_shim_decl(
write!(out, ", ");
}
write_type_space(out, &arg.ty);
write!(out, "{}", arg.ident);
write!(out, "{}", arg.name.cxx);
}
if indirect_call {
if !sig.args.is_empty() {
@ -973,7 +968,7 @@ fn write_rust_function_shim_impl(
out.builtin.manually_drop = true;
write!(out, " ::rust::ManuallyDrop<");
write_type(out, &arg.ty);
writeln!(out, "> {}$(::std::move({0}));", arg.ident);
writeln!(out, "> {}$(::std::move({0}));", arg.name.cxx);
}
}
write!(out, " ");
@ -1037,7 +1032,7 @@ fn write_rust_function_shim_impl(
ty if out.types.needs_indirect_abi(ty) => write!(out, "&"),
_ => {}
}
write!(out, "{}", arg.ident);
write!(out, "{}", arg.name.cxx);
match &arg.ty {
Type::RustBox(_) => write!(out, ".into_raw()"),
Type::UniquePtr(_) => write!(out, ".release()"),
@ -1158,7 +1153,7 @@ fn write_extern_arg(out: &mut OutFile, arg: &Var) {
if out.types.needs_indirect_abi(&arg.ty) {
write!(out, "*");
}
write!(out, "{}", arg.ident);
write!(out, "{}", arg.name.cxx);
}
fn write_type(out: &mut OutFile, ty: &Type) {

View File

@ -104,9 +104,9 @@ fn struct_clone(strct: &Struct, span: Span) -> TokenStream {
let body = if derive::contains(&strct.derives, Trait::Copy) {
quote!(*self)
} else {
let fields = strct.fields.iter().map(|field| &field.ident);
let fields = strct.fields.iter().map(|field| &field.name.rust);
let values = strct.fields.iter().map(|field| {
let ident = &field.ident;
let ident = &field.name.rust;
let ty = field.ty.to_token_stream();
let span = ty.into_iter().last().unwrap().span();
quote_spanned!(span=> &self.#ident)
@ -128,7 +128,7 @@ fn struct_clone(strct: &Struct, span: Span) -> TokenStream {
fn struct_debug(strct: &Struct, span: Span) -> TokenStream {
let ident = &strct.name.rust;
let struct_name = ident.to_string();
let fields = strct.fields.iter().map(|field| &field.ident);
let fields = strct.fields.iter().map(|field| &field.name.rust);
let field_names = fields.clone().map(Ident::to_string);
quote_spanned! {span=>
@ -144,7 +144,7 @@ fn struct_debug(strct: &Struct, span: Span) -> TokenStream {
fn struct_default(strct: &Struct, span: Span) -> TokenStream {
let ident = &strct.name.rust;
let fields = strct.fields.iter().map(|field| &field.ident);
let fields = strct.fields.iter().map(|field| &field.name.rust);
quote_spanned! {span=>
impl ::std::default::Default for #ident {
@ -161,7 +161,7 @@ fn struct_default(strct: &Struct, span: Span) -> TokenStream {
fn struct_ord(strct: &Struct, span: Span) -> TokenStream {
let ident = &strct.name.rust;
let fields = strct.fields.iter().map(|field| &field.ident);
let fields = strct.fields.iter().map(|field| &field.name.rust);
quote_spanned! {span=>
impl ::std::cmp::Ord for #ident {
@ -186,7 +186,7 @@ fn struct_partial_ord(strct: &Struct, span: Span) -> TokenStream {
::std::option::Option::Some(::std::cmp::Ord::cmp(self, other))
}
} else {
let fields = strct.fields.iter().map(|field| &field.ident);
let fields = strct.fields.iter().map(|field| &field.name.rust);
quote! {
#(
match ::std::cmp::PartialOrd::partial_cmp(&self.#fields, &other.#fields) {

View File

@ -395,7 +395,7 @@ fn expand_cxx_function_decl(efn: &ExternFn, types: &Types) -> TokenStream {
quote!(_: #receiver_type)
});
let args = efn.args.iter().map(|arg| {
let ident = &arg.ident;
let ident = &arg.name.rust;
let ty = expand_extern_type(&arg.ty, types, true);
if arg.ty == RustString {
quote!(#ident: *const #ty)
@ -461,7 +461,7 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
.iter()
.map(|receiver| receiver.var.to_token_stream());
let arg_vars = efn.args.iter().map(|arg| {
let var = &arg.ident;
let var = &arg.name.rust;
match &arg.ty {
Type::Ident(ident) if ident.rust == RustString => {
quote!(#var.as_mut_ptr() as *const ::cxx::private::RustString)
@ -503,7 +503,7 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
.iter()
.filter_map(|arg| {
if let Type::Fn(f) = &arg.ty {
let var = &arg.ident;
let var = &arg.name;
Some(expand_function_pointer_trampoline(efn, var, f, types))
} else {
None
@ -515,7 +515,7 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
.iter()
.filter(|arg| types.needs_indirect_abi(&arg.ty))
.map(|arg| {
let var = &arg.ident;
let var = &arg.name.rust;
// These are arguments for which C++ has taken ownership of the data
// behind the mut reference it received.
quote! {
@ -632,14 +632,14 @@ fn expand_cxx_function_shim(efn: &ExternFn, types: &Types) -> TokenStream {
fn expand_function_pointer_trampoline(
efn: &ExternFn,
var: &Ident,
var: &Pair,
sig: &Signature,
types: &Types,
) -> TokenStream {
let c_trampoline = mangle::c_trampoline(efn, var, types);
let r_trampoline = mangle::r_trampoline(efn, var, types);
let local_name = parse_quote!(__);
let catch_unwind_label = format!("::{}::{}", efn.name.rust, var);
let catch_unwind_label = format!("::{}::{}", efn.name.rust, var.rust);
let shim = expand_rust_function_shim_impl(
sig,
types,
@ -648,6 +648,7 @@ fn expand_function_pointer_trampoline(
catch_unwind_label,
None,
);
let var = &var.rust;
quote! {
let #var = ::cxx::private::FatFunction {
@ -792,7 +793,7 @@ fn expand_rust_function_shim_impl(
quote!(#receiver_var: #receiver_type)
});
let args = sig.args.iter().map(|arg| {
let ident = &arg.ident;
let ident = &arg.name.rust;
let ty = expand_extern_type(&arg.ty, types, false);
if types.needs_indirect_abi(&arg.ty) {
quote!(#ident: *mut #ty)
@ -803,7 +804,7 @@ fn expand_rust_function_shim_impl(
let all_args = receiver.into_iter().chain(args);
let arg_vars = sig.args.iter().map(|arg| {
let ident = &arg.ident;
let ident = &arg.name.rust;
match &arg.ty {
Type::Ident(i) if i.rust == RustString => {
quote!(::std::mem::take((*#ident).as_mut_string()))
@ -969,7 +970,7 @@ fn expand_rust_function_shim_super(
expand_return_type(&sig.ret)
};
let arg_vars = sig.args.iter().map(|arg| &arg.ident);
let arg_vars = sig.args.iter().map(|arg| &arg.name.rust);
let vars = receiver_var.iter().chain(arg_vars);
let span = invoke.span();

View File

@ -26,7 +26,7 @@ pub(crate) fn check_all(cx: &mut Check, apis: &[Api]) {
Api::Struct(strct) => {
check_ident(cx, &strct.name);
for field in &strct.fields {
check(cx, &field.ident);
check_ident(cx, &field.name);
}
}
Api::Enum(enm) => {
@ -41,7 +41,7 @@ pub(crate) fn check_all(cx: &mut Check, apis: &[Api]) {
Api::CxxFunction(efn) | Api::RustFunction(efn) => {
check(cx, &efn.name.rust);
for arg in &efn.args {
check(cx, &arg.ident);
check_ident(cx, &arg.name);
}
}
Api::TypeAlias(alias) => {

View File

@ -301,14 +301,14 @@ impl PartialEq for Signature {
doc: _,
attrs: _,
visibility: _,
ident: _,
name: _,
ty,
} = arg;
let Var {
doc: _,
attrs: _,
visibility: _,
ident: _,
name: _,
ty: ty2,
} = arg2;
ty == ty2
@ -336,7 +336,7 @@ impl Hash for Signature {
doc: _,
attrs: _,
visibility: _,
ident: _,
name: _,
ty,
} = arg;
ty.hash(state);

View File

@ -1,6 +1,5 @@
use crate::syntax::symbol::{self, Symbol};
use crate::syntax::{ExternFn, Pair, Types};
use proc_macro2::Ident;
const CXXBRIDGE: &str = "cxxbridge1";
@ -36,11 +35,11 @@ pub fn operator(receiver: &Pair, operator: &'static str) -> Symbol {
}
// The C half of a function pointer trampoline.
pub fn c_trampoline(efn: &ExternFn, var: &Ident, types: &Types) -> Symbol {
join!(extern_fn(efn, types), var, 0)
pub fn c_trampoline(efn: &ExternFn, var: &Pair, types: &Types) -> Symbol {
join!(extern_fn(efn, types), var.rust, 0)
}
// The Rust half of a function pointer trampoline.
pub fn r_trampoline(efn: &ExternFn, var: &Ident, types: &Types) -> Symbol {
join!(extern_fn(efn, types), var, 1)
pub fn r_trampoline(efn: &ExternFn, var: &Pair, types: &Types) -> Symbol {
join!(extern_fn(efn, types), var.rust, 1)
}

View File

@ -167,7 +167,7 @@ pub struct Var {
pub doc: Doc,
pub attrs: OtherAttrs,
pub visibility: Token![pub],
pub ident: Ident,
pub name: Pair,
pub ty: Type,
}

View File

@ -116,11 +116,12 @@ fn parse_struct(cx: &mut Errors, mut item: ItemStruct, namespace: &Namespace) ->
}
};
let visibility = visibility_pub(&field.vis, &ident);
let name = pair(Namespace::default(), &ident, None, None);
fields.push(Var {
doc,
attrs,
visibility,
ident,
name,
ty,
});
}
@ -541,11 +542,12 @@ fn parse_extern_fn(
let doc = Doc::new();
let attrs = OtherAttrs::none();
let visibility = Token![pub](ident.span());
let name = pair(Namespace::default(), &ident, None, None);
args.push_value(Var {
doc,
attrs,
visibility,
ident,
name,
ty,
});
if let Some(comma) = comma {
@ -1177,11 +1179,12 @@ fn parse_type_fn(ty: &TypeBareFn) -> Result<Type> {
let doc = Doc::new();
let attrs = OtherAttrs::none();
let visibility = Token![pub](ident.span());
let name = pair(Namespace::default(), &ident, None, None);
Ok(Var {
doc,
attrs,
visibility,
ident,
name,
ty,
})
})

View File

@ -41,11 +41,11 @@ impl ToTokens for Var {
doc: _,
attrs: _,
visibility: _,
ident,
name,
ty,
} = self;
ident.to_tokens(tokens);
Token![:](ident.span()).to_tokens(tokens);
name.rust.to_tokens(tokens);
Token![:](name.rust.span()).to_tokens(tokens);
ty.to_tokens(tokens);
}
}