Fix previous commit.
diff --git a/gen/src/write.rs b/gen/src/write.rs
index 2ea6ca8..70620ce 100644
--- a/gen/src/write.rs
+++ b/gen/src/write.rs
@@ -5,7 +5,7 @@
use crate::syntax::symbol::Symbol;
use crate::syntax::{mangle, Api, Enum, ExternFn, ExternType, Signature, Struct, Type, Types, Var};
use proc_macro2::Ident;
-use std::collections::{HashMap, HashSet};
+use std::collections::HashMap;
pub(super) fn gen(
namespace: &Namespace,
@@ -46,7 +46,6 @@
}
}
- let mut cxx_types = HashSet::new();
let mut methods_for_type = HashMap::new();
for api in apis {
if let Api::RustFunction(efn) = api {
@@ -57,9 +56,6 @@
.push(efn);
}
}
- if let Api::CxxType(enm) = api {
- cxx_types.insert(&enm.ident);
- }
}
for api in apis {
@@ -70,7 +66,7 @@
}
Api::Enum(enm) => {
out.next_section();
- if cxx_types.contains(&enm.ident) {
+ if types.cxx.contains(&enm.ident) {
check_enum(out, enm);
} else {
write_enum(out, enm);
@@ -382,31 +378,24 @@
}
fn check_enum(out: &mut OutFile, enm: &Enum) {
- let discriminants = enm
- .variants
- .iter()
- .scan(None, |prev_discriminant, variant| {
- let discriminant = variant
- .discriminant
- .unwrap_or_else(|| prev_discriminant.map_or(0, |n| n + 1));
- *prev_discriminant = Some(discriminant);
- Some(discriminant)
- });
writeln!(
out,
"static_assert(sizeof({}) == sizeof(uint32_t));",
enm.ident
);
- enm.variants
- .iter()
- .zip(discriminants)
- .for_each(|(variant, discriminant)| {
- writeln!(
- out,
- "static_assert({}::{} == {});",
- enm.ident, variant.ident, discriminant
- );
- });
+ let mut prev_discriminant = None;
+ for variant in &enm.variants {
+ let discriminant = variant
+ .discriminant
+ .unwrap_or_else(|| prev_discriminant.map_or(0, |n| n + 1));
+ writeln!(
+ out,
+ "static_assert(static_cast<uint32_t>({}::{}) == {},
+ \"disagrees with the value in #[cxx::bridge]\");",
+ enm.ident, variant.ident, discriminant,
+ );
+ prev_discriminant = Some(discriminant);
+ }
}
fn write_exception_glue(out: &mut OutFile, apis: &[Api]) {
diff --git a/macro/src/expand.rs b/macro/src/expand.rs
index 1a23960..d8810dc 100644
--- a/macro/src/expand.rs
+++ b/macro/src/expand.rs
@@ -7,7 +7,6 @@
};
use proc_macro2::{Ident, Span, TokenStream};
use quote::{format_ident, quote, quote_spanned, ToTokens};
-use std::collections::HashSet;
use syn::{parse_quote, Error, ItemMod, Result, Token};
pub fn bridge(namespace: &Namespace, mut ffi: ItemMod) -> Result<TokenStream> {
@@ -40,19 +39,13 @@
}
}
- let mut enums = HashSet::new();
- for api in apis {
- if let Api::Enum(enm) = api {
- enums.insert(&enm.ident);
- }
- }
for api in apis {
match api {
Api::Include(_) | Api::RustType(_) => {}
Api::Struct(strct) => expanded.extend(expand_struct(strct)),
Api::Enum(enm) => expanded.extend(expand_enum(enm)),
Api::CxxType(ety) => {
- if !enums.contains(&ety.ident) {
+ if !types.enums.contains_key(&ety.ident) {
expanded.extend(expand_cxx_type(ety));
}
}
diff --git a/syntax/types.rs b/syntax/types.rs
index bfe7bf0..5800513 100644
--- a/syntax/types.rs
+++ b/syntax/types.rs
@@ -61,11 +61,12 @@
}
Api::Enum(enm) => {
let ident = &enm.ident;
- if type_names.insert(ident) {
- enums.insert(ident.clone(), enm);
- } else {
+ // We allow declaring the same type as a shared enum and as a Cxxtype, as this
+ // means not to emit the C++ enum definition.
+ if !type_names.insert(ident) && !cxx.contains(ident) {
duplicate_name(cx, enm, ident);
}
+ enums.insert(ident.clone(), enm);
}
Api::CxxType(ety) => {
let ident = &ety.ident;
diff --git a/tests/ffi/lib.rs b/tests/ffi/lib.rs
index 0162c9b..16846fb 100644
--- a/tests/ffi/lib.rs
+++ b/tests/ffi/lib.rs
@@ -84,6 +84,15 @@
fn set2(&mut self, n: usize) -> usize;
}
+ extern "C" {
+ type COwnedEnum;
+ }
+
+ enum COwnedEnum {
+ CVal1,
+ CVal2,
+ }
+
extern "Rust" {
type R;
type R2;
diff --git a/tests/ffi/tests.h b/tests/ffi/tests.h
index d3b7d38..795b4a9 100644
--- a/tests/ffi/tests.h
+++ b/tests/ffi/tests.h
@@ -23,6 +23,11 @@
std::vector<uint8_t> v;
};
+enum COwnedEnum {
+ CVal1,
+ CVal2,
+};
+
size_t c_return_primitive();
Shared c_return_shared();
rust::Box<R> c_return_box();