Skip to content

Commit 978f221

Browse files
committed
Handle empty enums without variants
When `repr(C)` is on a Rust `enum`, it cannot be empty, so we need to add a dummy.
1 parent 6b4718a commit 978f221

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+222
-279
lines changed

src/codegen/mod.rs

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2148,7 +2148,10 @@ impl EnumVariation {
21482148

21492149
/// A helper type to construct different enum variations.
21502150
enum EnumBuilder<'a> {
2151-
Rust(quote::Tokens),
2151+
Rust {
2152+
tokens: quote::Tokens,
2153+
emitted_any_variants: bool,
2154+
},
21522155
Bitfield {
21532156
canonical_name: &'a str,
21542157
tokens: quote::Tokens,
@@ -2185,11 +2188,13 @@ impl<'a> EnumBuilder<'a> {
21852188
EnumVariation::Rust => {
21862189
let mut tokens = quote! {
21872190
#( #attrs )*
2188-
#[repr(C)]
21892191
pub enum #ident
21902192
};
21912193
tokens.append("{");
2192-
EnumBuilder::Rust(tokens)
2194+
EnumBuilder::Rust {
2195+
tokens,
2196+
emitted_any_variants: false,
2197+
}
21932198
}
21942199

21952200
EnumVariation::Consts => {
@@ -2230,12 +2235,15 @@ impl<'a> EnumBuilder<'a> {
22302235
};
22312236

22322237
match self {
2233-
EnumBuilder::Rust(tokens) => {
2238+
EnumBuilder::Rust { tokens, emitted_any_variants: _ } => {
22342239
let name = ctx.rust_ident(variant_name);
2235-
EnumBuilder::Rust(quote! {
2236-
#tokens
2237-
#name = #expr,
2238-
})
2240+
EnumBuilder::Rust {
2241+
tokens: quote! {
2242+
#tokens
2243+
#name = #expr,
2244+
},
2245+
emitted_any_variants: true,
2246+
}
22392247
}
22402248

22412249
EnumBuilder::Bitfield { .. } => {
@@ -2296,9 +2304,12 @@ impl<'a> EnumBuilder<'a> {
22962304
result: &mut CodegenResult<'b>,
22972305
) -> quote::Tokens {
22982306
match self {
2299-
EnumBuilder::Rust(mut t) => {
2300-
t.append("}");
2301-
t
2307+
EnumBuilder::Rust { mut tokens, emitted_any_variants } => {
2308+
if !emitted_any_variants {
2309+
tokens.append(quote! { __bindgen_cannot_repr_c_on_empty_enum = 0 });
2310+
}
2311+
tokens.append("}");
2312+
tokens
23022313
}
23032314
EnumBuilder::Bitfield {
23042315
canonical_name,
@@ -2433,15 +2444,12 @@ impl CodeGenerator for Enum {
24332444

24342445
let mut attrs = vec![];
24352446

2436-
// FIXME: Rust forbids repr with empty enums. Remove this condition when
2437-
// this is allowed.
2438-
//
24392447
// TODO(emilio): Delegate this to the builders?
24402448
if variation.is_rust() {
2441-
if !self.variants().is_empty() {
2442-
attrs.push(attributes::repr(repr_name));
2443-
}
2444-
} else if variation.is_bitfield() {
2449+
attrs.push(attributes::repr(repr_name));
2450+
}
2451+
2452+
if variation.is_bitfield() || variation.is_rust() {
24452453
attrs.push(attributes::repr("C"));
24462454
}
24472455

tests/expectations/tests/anon_enum.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ pub struct Test {
1212
}
1313
pub const Test_T_NONE: Test__bindgen_ty_1 = Test__bindgen_ty_1::T_NONE;
1414
#[repr(u32)]
15-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1615
#[repr(C)]
16+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1717
pub enum Test__bindgen_ty_1 {
1818
T_NONE = 0,
1919
}
@@ -41,8 +41,8 @@ fn bindgen_test_layout_Test() {
4141
);
4242
}
4343
#[repr(u32)]
44-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
4544
#[repr(C)]
45+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
4646
pub enum Baz {
4747
Foo = 0,
4848
Bar = 1,

tests/expectations/tests/anon_enum_trait.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ pub const DataType_channels: DataType__bindgen_ty_1 = DataType__bindgen_ty_1::ge
1919
pub const DataType_fmt: DataType__bindgen_ty_1 = DataType__bindgen_ty_1::generic_type;
2020
pub const DataType_type_: DataType__bindgen_ty_1 = DataType__bindgen_ty_1::generic_type;
2121
#[repr(i32)]
22-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2322
#[repr(C)]
23+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2424
pub enum DataType__bindgen_ty_1 {
2525
generic_type = 0,
2626
}
@@ -32,8 +32,8 @@ pub struct Foo {
3232
pub const Foo_Bar: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::Bar;
3333
pub const Foo_Baz: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::Bar;
3434
#[repr(u32)]
35-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
3635
#[repr(C)]
36+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
3737
pub enum Foo__bindgen_ty_1 {
3838
Bar = 0,
3939
}

tests/expectations/tests/anon_enum_whitelist.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
pub const NODE_FLAG_FOO: _bindgen_ty_1 = _bindgen_ty_1::NODE_FLAG_FOO;
88
pub const NODE_FLAG_BAR: _bindgen_ty_1 = _bindgen_ty_1::NODE_FLAG_BAR;
99
#[repr(u32)]
10-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1110
#[repr(C)]
11+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1212
pub enum _bindgen_ty_1 {
1313
NODE_FLAG_FOO = 0,
1414
NODE_FLAG_BAR = 1,

tests/expectations/tests/anon_union.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ pub struct TErrorResult {
1414
pub const TErrorResult_UnionState_HasException: TErrorResult_UnionState =
1515
TErrorResult_UnionState::HasMessage;
1616
#[repr(i32)]
17-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1817
#[repr(C)]
18+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1919
pub enum TErrorResult_UnionState {
2020
HasMessage = 0,
2121
}

tests/expectations/tests/anon_union_1_0.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ pub struct TErrorResult {
5858
pub const TErrorResult_UnionState_HasException: TErrorResult_UnionState =
5959
TErrorResult_UnionState::HasMessage;
6060
#[repr(i32)]
61-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
6261
#[repr(C)]
62+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
6363
pub enum TErrorResult_UnionState {
6464
HasMessage = 0,
6565
}

tests/expectations/tests/bitfield_align_2.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ where
8484
}
8585
}
8686
#[repr(u32)]
87-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
8887
#[repr(C)]
88+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
8989
pub enum MyEnum {
9090
ONE = 0,
9191
TWO = 1,

tests/expectations/tests/class_with_inner_struct.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,8 @@ fn bindgen_test_layout_B() {
214214
);
215215
}
216216
#[repr(i32)]
217-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
218217
#[repr(C)]
218+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
219219
pub enum StepSyntax {
220220
Keyword = 0,
221221
FunctionalWithoutKeyword = 1,

tests/expectations/tests/class_with_inner_struct_1_0.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,8 @@ impl Clone for B {
272272
}
273273
}
274274
#[repr(i32)]
275-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
276275
#[repr(C)]
276+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
277277
pub enum StepSyntax {
278278
Keyword = 0,
279279
FunctionalWithoutKeyword = 1,

tests/expectations/tests/const_enum_unnamed.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
pub const FOO_BAR: _bindgen_ty_1 = _bindgen_ty_1::FOO_BAR;
88
pub const FOO_BAZ: _bindgen_ty_1 = _bindgen_ty_1::FOO_BAZ;
99
#[repr(u32)]
10-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1110
#[repr(C)]
11+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1212
pub enum _bindgen_ty_1 {
1313
FOO_BAR = 0,
1414
FOO_BAZ = 1,
@@ -20,8 +20,8 @@ pub struct Foo {
2020
}
2121
pub const Foo_FOO_BAR: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::FOO_BAR;
2222
#[repr(u32)]
23-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2423
#[repr(C)]
24+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2525
pub enum Foo__bindgen_ty_1 {
2626
FOO_BAR = 10,
2727
}

tests/expectations/tests/constify-enum.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ pub const nsCSSPropertyID_eCSSProperty_COUNT_unexistingVariantValue: nsCSSProper
99
pub const nsCSSPropertyID_eCSSProperty_COUNT: nsCSSPropertyID =
1010
nsCSSPropertyID::eCSSPropertyAlias_aa;
1111
#[repr(u32)]
12-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1312
#[repr(C)]
13+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1414
pub enum nsCSSPropertyID {
1515
eCSSProperty_a = 0,
1616
eCSSProperty_b = 1,
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
5+
6+
7+
pub type EmptyConstified = ::std::os::raw::c_uint;
8+
#[repr(u32)]
9+
#[repr(C)]
10+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
11+
pub enum EmptyRustified {
12+
__bindgen_cannot_repr_c_on_empty_enum = 0,
13+
}
14+
pub mod EmptyModule {
15+
pub type Type = ::std::os::raw::c_uint;
16+
}
17+
#[repr(i8)]
18+
#[repr(C)]
19+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
20+
pub enum EmptyClassRustified {
21+
__bindgen_cannot_repr_c_on_empty_enum = 0,
22+
}
23+
pub type EmptyClassConstified = ::std::os::raw::c_char;
24+
pub mod EmptyClassModule {
25+
pub type Type = ::std::os::raw::c_char;
26+
}
27+
#[repr(i8)]
28+
#[repr(C)]
29+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
30+
pub enum ForwardClassRustified {
31+
__bindgen_cannot_repr_c_on_empty_enum = 0,
32+
}
33+
pub type ForwardClassConstified = ::std::os::raw::c_char;
34+
pub mod ForwardClassModule {
35+
pub type Type = ::std::os::raw::c_char;
36+
}

tests/expectations/tests/enum.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55

66

77
#[repr(u32)]
8-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
98
#[repr(C)]
9+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1010
pub enum Foo {
1111
Bar = 0,
1212
Qux = 1,
1313
}
1414
#[repr(i32)]
15-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1615
#[repr(C)]
16+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1717
pub enum Neg {
1818
MinusOne = -1,
1919
One = 1,

tests/expectations/tests/enum_alias.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66

77
#[repr(u8)]
8-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
98
#[repr(C)]
9+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1010
pub enum Bar {
1111
VAL = 0,
1212
}

tests/expectations/tests/enum_and_vtable_mangling.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
pub const match_: _bindgen_ty_1 = _bindgen_ty_1::match_;
88
pub const whatever_else: _bindgen_ty_1 = _bindgen_ty_1::whatever_else;
99
#[repr(u32)]
10-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1110
#[repr(C)]
11+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1212
pub enum _bindgen_ty_1 {
1313
match_ = 0,
1414
whatever_else = 1,

tests/expectations/tests/enum_dupe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
pub const Foo_Dupe: Foo = Foo::Bar;
88
#[repr(u32)]
9-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
109
#[repr(C)]
10+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1111
pub enum Foo {
1212
Bar = 1,
1313
}

tests/expectations/tests/enum_explicit_type.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,41 +5,41 @@
55

66

77
#[repr(u8)]
8-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
98
#[repr(C)]
9+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1010
pub enum Foo {
1111
Bar = 0,
1212
Qux = 1,
1313
}
1414
#[repr(i8)]
15-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1615
#[repr(C)]
16+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1717
pub enum Neg {
1818
MinusOne = -1,
1919
One = 1,
2020
}
2121
#[repr(u16)]
22-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2322
#[repr(C)]
23+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2424
pub enum Bigger {
2525
Much = 255,
2626
Larger = 256,
2727
}
2828
#[repr(i64)]
29-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
3029
#[repr(C)]
30+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
3131
pub enum MuchLong {
3232
MuchLow = -4294967296,
3333
}
3434
#[repr(i64)]
35-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
3635
#[repr(C)]
36+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
3737
pub enum MuchLongLong {
3838
I64_MIN = -9223372036854775808,
3939
}
4040
#[repr(u64)]
41-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
4241
#[repr(C)]
42+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
4343
pub enum MuchULongLong {
4444
MuchHigh = 4294967296,
4545
}

tests/expectations/tests/enum_in_template_with_typedef.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ pub type std_fbstring_core_category_type = u8;
1313
pub const std_fbstring_core_Category_Bar: std_fbstring_core_Category =
1414
std_fbstring_core_Category::Foo;
1515
#[repr(u8)]
16-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1716
#[repr(C)]
17+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1818
pub enum std_fbstring_core_Category {
1919
Foo = 0,
2020
}

tests/expectations/tests/enum_negative.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55

66

77
#[repr(i32)]
8-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
98
#[repr(C)]
9+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1010
pub enum Foo {
1111
Bar = -2,
1212
Qux = 1,

tests/expectations/tests/enum_packed.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,22 @@
55

66

77
#[repr(u8)]
8-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
98
#[repr(C)]
9+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1010
pub enum Foo {
1111
Bar = 0,
1212
Qux = 1,
1313
}
1414
#[repr(i8)]
15-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1615
#[repr(C)]
16+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1717
pub enum Neg {
1818
MinusOne = -1,
1919
One = 1,
2020
}
2121
#[repr(u16)]
22-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2322
#[repr(C)]
23+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2424
pub enum Bigger {
2525
Much = 255,
2626
Larger = 256,

0 commit comments

Comments
 (0)