Store independent rust name and c++ name for extern functions
diff --git a/syntax/check.rs b/syntax/check.rs
index ff23ec9..2f3c334 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -214,8 +214,8 @@
if let Some(reason) = cx.types.required_trivial.get(&ety.ident) {
let what = match reason {
TrivialReason::StructField(strct) => format!("a field of `{}`", strct.ident),
- TrivialReason::FunctionArgument(efn) => format!("an argument of `{}`", efn.ident),
- TrivialReason::FunctionReturn(efn) => format!("a return value of `{}`", efn.ident),
+ TrivialReason::FunctionArgument(efn) => format!("an argument of `{}`", efn.ident.rust),
+ TrivialReason::FunctionReturn(efn) => format!("a return value of `{}`", efn.ident.rust),
};
let msg = format!(
"needs a cxx::ExternType impl in order to be used as {}",
diff --git a/syntax/ident.rs b/syntax/ident.rs
index 74e7799..66f7365 100644
--- a/syntax/ident.rs
+++ b/syntax/ident.rs
@@ -37,7 +37,7 @@
check(cx, &ety.ident);
}
Api::CxxFunction(efn) | Api::RustFunction(efn) => {
- check(cx, &efn.ident);
+ check(cx, &efn.ident.rust);
for arg in &efn.args {
check(cx, &arg.ident);
}
diff --git a/syntax/mangle.rs b/syntax/mangle.rs
index 72233b3..e461887 100644
--- a/syntax/mangle.rs
+++ b/syntax/mangle.rs
@@ -13,8 +13,8 @@
pub fn extern_fn(namespace: &Namespace, efn: &ExternFn) -> Symbol {
match &efn.receiver {
- Some(receiver) => join!(namespace, CXXBRIDGE, receiver.ty, efn.ident),
- None => join!(namespace, CXXBRIDGE, efn.ident),
+ Some(receiver) => join!(namespace, CXXBRIDGE, receiver.ty, efn.ident.rust),
+ None => join!(namespace, CXXBRIDGE, efn.ident.rust),
}
}
diff --git a/syntax/mod.rs b/syntax/mod.rs
index 934f6c6..c8dea67 100644
--- a/syntax/mod.rs
+++ b/syntax/mod.rs
@@ -71,10 +71,15 @@
pub repr: Atom,
}
+pub struct Pair {
+ pub cxx: Ident,
+ pub rust: Ident,
+}
+
pub struct ExternFn {
pub lang: Lang,
pub doc: Doc,
- pub ident: Ident,
+ pub ident: Pair,
pub sig: Signature,
pub semi_token: Token![;],
}
diff --git a/syntax/parse.rs b/syntax/parse.rs
index c611c8b..142d063 100644
--- a/syntax/parse.rs
+++ b/syntax/parse.rs
@@ -3,7 +3,7 @@
use crate::syntax::report::Errors;
use crate::syntax::Atom::*;
use crate::syntax::{
- attrs, error, Api, Doc, Enum, ExternFn, ExternType, Impl, Lang, Receiver, Ref, Signature,
+ attrs, error, Api, Doc, Enum, ExternFn, ExternType, Impl, Lang, Pair, Receiver, Ref, Signature,
Slice, Struct, Ty1, Type, TypeAlias, Var, Variant,
};
use proc_macro2::{Delimiter, Group, TokenStream, TokenTree};
@@ -370,7 +370,10 @@
Ok(api_function(ExternFn {
lang,
doc,
- ident,
+ ident: Pair {
+ cxx: ident.clone(),
+ rust: ident,
+ },
sig: Signature {
unsafety,
fn_token,
diff --git a/syntax/types.rs b/syntax/types.rs
index 3f8d10c..5ec7d26 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -51,7 +51,8 @@
}
let mut type_names = UnorderedSet::new();
- let mut function_names = UnorderedSet::new();
+ let mut cxx_function_names = UnorderedSet::new();
+ let mut rust_function_names = UnorderedSet::new();
for api in apis {
// The same identifier is permitted to be declared as both a shared
// enum and extern C++ type, or shared struct and extern C++ type.
@@ -116,9 +117,15 @@
rust.insert(ident);
}
Api::CxxFunction(efn) | Api::RustFunction(efn) => {
- let ident = &efn.ident;
- if !function_names.insert((&efn.receiver, ident)) {
- duplicate_name(cx, efn, ident);
+ let cxx_fn = (&efn.receiver, &efn.ident.cxx);
+ let rust_fn = (&efn.receiver, &efn.ident.rust);
+ let cxx_duplicate = !cxx_function_names.insert(cxx_fn);
+ if !rust_function_names.insert(rust_fn) {
+ duplicate_name(cx, efn, &efn.ident.rust);
+ } else if cxx_duplicate {
+ // Insert into cxx_function_names either way, but hide
+ // error if we're already erroring on the rust name.
+ duplicate_name(cx, efn, &efn.ident.cxx);
}
for arg in &efn.args {
visit(&mut all, &arg.ty);