Collect reason that each alias is required trivial
diff --git a/gen/src/write.rs b/gen/src/write.rs
index ddde8a9..1f4b7bc 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -81,7 +81,7 @@
}
}
Api::TypeAlias(ety) => {
- if types.required_trivial_aliases.contains(&ety.ident) {
+ if types.required_trivial_aliases.contains_key(&ety.ident) {
check_trivial_extern_type(out, &ety.ident)
}
}
@@ -136,7 +136,7 @@
Some(CxxString) => out.include.string = true,
Some(Bool) | Some(Isize) | Some(F32) | Some(F64) | Some(RustString) => {}
None => {
- if types.required_trivial_aliases.contains(&ident) {
+ if types.required_trivial_aliases.contains_key(&ident) {
out.include.type_traits = true;
}
}
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 02817a4..739529f 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -683,7 +683,7 @@
const _: fn() = #begin #ident, #type_id #end;
};
- if types.required_trivial_aliases.contains(&alias.ident) {
+ if types.required_trivial_aliases.contains_key(&alias.ident) {
let begin = quote_spanned!(begin_span=> ::cxx::private::verify_extern_kind::<);
verify.extend(quote! {
const _: fn() = #begin #ident, ::cxx::kind::Trivial #end;
diff --git a/syntax/check.rs b/syntax/check.rs
index cfac236..1543918 100644
--- a/syntax/check.rs
+++ b/syntax/check.rs
@@ -338,7 +338,7 @@
|| cx.types.cxx.contains(ident)
&& !cx.types.structs.contains_key(ident)
&& !cx.types.enums.contains_key(ident)
- && !cx.types.required_trivial_aliases.contains(ident)
+ && !cx.types.required_trivial_aliases.contains_key(ident)
|| cx.types.rust.contains(ident)
}
@@ -377,7 +377,7 @@
} else if cx.types.enums.contains_key(ident) {
"enum".to_owned()
} else if cx.types.cxx.contains(ident) {
- if cx.types.required_trivial_aliases.contains(ident) {
+ if cx.types.required_trivial_aliases.contains_key(ident) {
"trivial C++ type".to_owned()
} else {
"non-trivial C++ type".to_owned()
diff --git a/syntax/types.rs b/syntax/types.rs
index 7eb22d4..efccb2b 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -1,7 +1,7 @@
use crate::syntax::atom::Atom::{self, *};
use crate::syntax::report::Errors;
use crate::syntax::set::OrderedSet as Set;
-use crate::syntax::{Api, Derive, Enum, ExternType, Struct, Type, TypeAlias};
+use crate::syntax::{Api, Derive, Enum, ExternFn, ExternType, Struct, Type, TypeAlias};
use proc_macro2::Ident;
use quote::ToTokens;
use std::collections::{BTreeMap as Map, HashSet as UnorderedSet};
@@ -14,7 +14,7 @@
pub rust: Set<&'a Ident>,
pub aliases: Map<&'a Ident, &'a TypeAlias>,
pub untrusted: Map<&'a Ident, &'a ExternType>,
- pub required_trivial_aliases: UnorderedSet<&'a Ident>,
+ pub required_trivial_aliases: Map<&'a Ident, TrivialReason<'a>>,
}
impl<'a> Types<'a> {
@@ -140,27 +140,30 @@
// we check that this is permissible. We do this _after_ scanning all
// the APIs above, in case some function or struct references a type
// which is declared subsequently.
- let mut required_trivial_aliases = UnorderedSet::new();
- let mut insist_alias_types_are_trivial = |ty: &'a Type| {
+ let mut required_trivial_aliases = Map::new();
+ let mut insist_alias_types_are_trivial = |ty: &'a Type, reason| {
if let Type::Ident(ident) = ty {
if aliases.contains_key(ident) {
- required_trivial_aliases.insert(ident);
+ required_trivial_aliases.entry(ident).or_insert(reason);
}
}
};
for api in apis {
match api {
Api::Struct(strct) => {
+ let reason = TrivialReason::StructField(strct);
for field in &strct.fields {
- insist_alias_types_are_trivial(&field.ty);
+ insist_alias_types_are_trivial(&field.ty, reason);
}
}
Api::CxxFunction(efn) | Api::RustFunction(efn) => {
+ let reason = TrivialReason::FunctionArgument(efn);
for arg in &efn.args {
- insist_alias_types_are_trivial(&arg.ty);
+ insist_alias_types_are_trivial(&arg.ty, reason);
}
if let Some(ret) = &efn.ret {
- insist_alias_types_are_trivial(&ret);
+ let reason = TrivialReason::FunctionReturn(efn);
+ insist_alias_types_are_trivial(&ret, reason);
}
}
_ => {}
@@ -211,6 +214,13 @@
}
}
+#[derive(Copy, Clone)]
+pub enum TrivialReason<'a> {
+ StructField(&'a Struct),
+ FunctionArgument(&'a ExternFn),
+ FunctionReturn(&'a ExternFn),
+}
+
fn duplicate_name(cx: &mut Errors, sp: impl ToTokens, ident: &Ident) {
let msg = format!("the name `{}` is defined multiple times", ident);
cx.error(sp, msg);