summaryrefslogtreecommitdiff
path: root/bindgen/codegen/mod.rs
diff options
context:
space:
mode:
authorDavid Tolnay <dtolnay@gmail.com>2022-11-28 06:40:20 -0800
committerGitHub <noreply@github.com>2022-11-28 09:40:20 -0500
commit0a78cde484fd5b6a5bbfd4301b3c4cf043a60a38 (patch)
treeec24cc604a33a0443999b77335fc29e70a722f2b /bindgen/codegen/mod.rs
parent95fd17b874910184cc0fcd33b287fa4e205d9d7a (diff)
Fix name collision between C enum and typedef (#2326)
Fixes #2008. Example: ```c enum Enum { Variant }; typedef int16_t Enum; ``` This is valid and idiomatic C (though not valid C++). `cbindgen` uses this idiom as the default C translation of Rust enums, the equivalent of what would be `enum Enum : int16_t { Variant };` in C++. `bindgen header.h` before: ```rust pub const Enum_Variant: Enum = 0; pub type Enum = ::std::os::raw::c_uint; pub type Enum = i16; ``` ```console error[E0428]: the name `Enum` is defined multiple times --> generated.rs:3:1 | 2 | pub type Enum = ::std::os::raw::c_uint; | --------------------------------------- previous definition of the type `Enum` here 3 | pub type Enum = i16; | ^^^^^^^^^^^^^^^^^^^^ `Enum` redefined here | = note: `Enum` must be defined only once in the type namespace of this module ``` After: ```rust pub const Enum_Variant: Enum = 0; pub type Enum = i16; ```
Diffstat (limited to 'bindgen/codegen/mod.rs')
-rw-r--r--bindgen/codegen/mod.rs15
1 files changed, 10 insertions, 5 deletions
diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs
index b4050637..154d7fd1 100644
--- a/bindgen/codegen/mod.rs
+++ b/bindgen/codegen/mod.rs
@@ -2709,6 +2709,7 @@ impl<'a> EnumBuilder<'a> {
mut attrs: Vec<proc_macro2::TokenStream>,
repr: proc_macro2::TokenStream,
enum_variation: EnumVariation,
+ has_typedef: bool,
) -> Self {
let ident = Ident::new(name, Span::call_site());
@@ -2741,10 +2742,12 @@ impl<'a> EnumBuilder<'a> {
EnumVariation::Consts => {
let mut variants = Vec::new();
- variants.push(quote! {
- #( #attrs )*
- pub type #ident = #repr;
- });
+ if !has_typedef {
+ variants.push(quote! {
+ #( #attrs )*
+ pub type #ident = #repr;
+ });
+ }
EnumBuilder::Consts { variants }
}
@@ -3157,8 +3160,10 @@ impl CodeGenerator for Enum {
}
let repr = repr.to_rust_ty_or_opaque(ctx, item);
+ let has_typedef = ctx.is_enum_typedef_combo(item.id());
- let mut builder = EnumBuilder::new(&name, attrs, repr, variation);
+ let mut builder =
+ EnumBuilder::new(&name, attrs, repr, variation, has_typedef);
// A map where we keep a value -> variant relation.
let mut seen_values = HashMap::<_, Ident>::default();