Skip to content

Commit 43c43ba

Browse files
committed
Always add repr(C) to rustified enums
If we don't, then eddyb's recent layout optimizations will do unexpected things to them. We also need to handle empty `enum`s without variants. When `repr(C)` is on a Rust `enum`, it cannot be empty, so we need to add a dummy.
1 parent d9950d4 commit 43c43ba

Some content is hidden

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

46 files changed

+171
-22
lines changed

src/codegen/mod.rs

+26-17
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,
@@ -2188,7 +2191,10 @@ impl<'a> EnumBuilder<'a> {
21882191
pub enum #ident
21892192
};
21902193
tokens.append("{");
2191-
EnumBuilder::Rust(tokens)
2194+
EnumBuilder::Rust {
2195+
tokens,
2196+
emitted_any_variants: false,
2197+
}
21922198
}
21932199

21942200
EnumVariation::Consts => {
@@ -2229,12 +2235,15 @@ impl<'a> EnumBuilder<'a> {
22292235
};
22302236

22312237
match self {
2232-
EnumBuilder::Rust(tokens) => {
2238+
EnumBuilder::Rust { tokens, emitted_any_variants: _ } => {
22332239
let name = ctx.rust_ident(variant_name);
2234-
EnumBuilder::Rust(quote! {
2235-
#tokens
2236-
#name = #expr,
2237-
})
2240+
EnumBuilder::Rust {
2241+
tokens: quote! {
2242+
#tokens
2243+
#name = #expr,
2244+
},
2245+
emitted_any_variants: true,
2246+
}
22382247
}
22392248

22402249
EnumBuilder::Bitfield { .. } => {
@@ -2295,9 +2304,12 @@ impl<'a> EnumBuilder<'a> {
22952304
result: &mut CodegenResult<'b>,
22962305
) -> quote::Tokens {
22972306
match self {
2298-
EnumBuilder::Rust(mut t) => {
2299-
t.append("}");
2300-
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
23012313
}
23022314
EnumBuilder::Bitfield {
23032315
canonical_name,
@@ -2432,15 +2444,12 @@ impl CodeGenerator for Enum {
24322444

24332445
let mut attrs = vec![];
24342446

2435-
// FIXME: Rust forbids repr with empty enums. Remove this condition when
2436-
// this is allowed.
2437-
//
24382447
// TODO(emilio): Delegate this to the builders?
24392448
if variation.is_rust() {
2440-
if !self.variants().is_empty() {
2441-
attrs.push(attributes::repr(repr_name));
2442-
}
2443-
} else if variation.is_bitfield() {
2449+
attrs.push(attributes::repr(repr_name));
2450+
}
2451+
2452+
if variation.is_bitfield() || variation.is_rust() {
24442453
attrs.push(attributes::repr("C"));
24452454
}
24462455

tests/expectations/tests/anon_enum.rs

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub struct Test {
1212
}
1313
pub const Test_T_NONE: Test__bindgen_ty_1 = Test__bindgen_ty_1::T_NONE;
1414
#[repr(u32)]
15+
#[repr(C)]
1516
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1617
pub enum Test__bindgen_ty_1 {
1718
T_NONE = 0,
@@ -40,6 +41,7 @@ fn bindgen_test_layout_Test() {
4041
);
4142
}
4243
#[repr(u32)]
44+
#[repr(C)]
4345
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
4446
pub enum Baz {
4547
Foo = 0,

tests/expectations/tests/anon_enum_trait.rs

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ 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+
#[repr(C)]
2223
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2324
pub enum DataType__bindgen_ty_1 {
2425
generic_type = 0,
@@ -31,6 +32,7 @@ pub struct Foo {
3132
pub const Foo_Bar: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::Bar;
3233
pub const Foo_Baz: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::Bar;
3334
#[repr(u32)]
35+
#[repr(C)]
3436
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
3537
pub enum Foo__bindgen_ty_1 {
3638
Bar = 0,

tests/expectations/tests/anon_enum_whitelist.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
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+
#[repr(C)]
1011
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1112
pub enum _bindgen_ty_1 {
1213
NODE_FLAG_FOO = 0,

tests/expectations/tests/anon_union.rs

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub struct TErrorResult {
1414
pub const TErrorResult_UnionState_HasException: TErrorResult_UnionState =
1515
TErrorResult_UnionState::HasMessage;
1616
#[repr(i32)]
17+
#[repr(C)]
1718
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1819
pub enum TErrorResult_UnionState {
1920
HasMessage = 0,

tests/expectations/tests/anon_union_1_0.rs

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ pub struct TErrorResult {
5858
pub const TErrorResult_UnionState_HasException: TErrorResult_UnionState =
5959
TErrorResult_UnionState::HasMessage;
6060
#[repr(i32)]
61+
#[repr(C)]
6162
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
6263
pub enum TErrorResult_UnionState {
6364
HasMessage = 0,

tests/expectations/tests/bitfield_align_2.rs

+1
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ where
8484
}
8585
}
8686
#[repr(u32)]
87+
#[repr(C)]
8788
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
8889
pub enum MyEnum {
8990
ONE = 0,

tests/expectations/tests/class_with_inner_struct.rs

+1
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ fn bindgen_test_layout_B() {
214214
);
215215
}
216216
#[repr(i32)]
217+
#[repr(C)]
217218
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
218219
pub enum StepSyntax {
219220
Keyword = 0,

tests/expectations/tests/class_with_inner_struct_1_0.rs

+1
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,7 @@ impl Clone for B {
272272
}
273273
}
274274
#[repr(i32)]
275+
#[repr(C)]
275276
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
276277
pub enum StepSyntax {
277278
Keyword = 0,

tests/expectations/tests/const_enum_unnamed.rs

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
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+
#[repr(C)]
1011
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1112
pub enum _bindgen_ty_1 {
1213
FOO_BAR = 0,
@@ -19,6 +20,7 @@ pub struct Foo {
1920
}
2021
pub const Foo_FOO_BAR: Foo__bindgen_ty_1 = Foo__bindgen_ty_1::FOO_BAR;
2122
#[repr(u32)]
23+
#[repr(C)]
2224
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2325
pub enum Foo__bindgen_ty_1 {
2426
FOO_BAR = 10,

tests/expectations/tests/constify-enum.rs

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pub const nsCSSPropertyID_eCSSProperty_COUNT_unexistingVariantValue: nsCSSProper
99
pub const nsCSSPropertyID_eCSSProperty_COUNT: nsCSSPropertyID =
1010
nsCSSPropertyID::eCSSPropertyAlias_aa;
1111
#[repr(u32)]
12+
#[repr(C)]
1213
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1314
pub enum nsCSSPropertyID {
1415
eCSSProperty_a = 0,
+36
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

+2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55

66

77
#[repr(u32)]
8+
#[repr(C)]
89
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
910
pub enum Foo {
1011
Bar = 0,
1112
Qux = 1,
1213
}
1314
#[repr(i32)]
15+
#[repr(C)]
1416
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1517
pub enum Neg {
1618
MinusOne = -1,

tests/expectations/tests/enum_alias.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66

77
#[repr(u8)]
8+
#[repr(C)]
89
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
910
pub enum Bar {
1011
VAL = 0,

tests/expectations/tests/enum_and_vtable_mangling.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
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+
#[repr(C)]
1011
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1112
pub enum _bindgen_ty_1 {
1213
match_ = 0,

tests/expectations/tests/enum_dupe.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
pub const Foo_Dupe: Foo = Foo::Bar;
88
#[repr(u32)]
9+
#[repr(C)]
910
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1011
pub enum Foo {
1112
Bar = 1,

tests/expectations/tests/enum_explicit_type.rs

+6
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,40 @@
55

66

77
#[repr(u8)]
8+
#[repr(C)]
89
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
910
pub enum Foo {
1011
Bar = 0,
1112
Qux = 1,
1213
}
1314
#[repr(i8)]
15+
#[repr(C)]
1416
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1517
pub enum Neg {
1618
MinusOne = -1,
1719
One = 1,
1820
}
1921
#[repr(u16)]
22+
#[repr(C)]
2023
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2124
pub enum Bigger {
2225
Much = 255,
2326
Larger = 256,
2427
}
2528
#[repr(i64)]
29+
#[repr(C)]
2630
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2731
pub enum MuchLong {
2832
MuchLow = -4294967296,
2933
}
3034
#[repr(i64)]
35+
#[repr(C)]
3136
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
3237
pub enum MuchLongLong {
3338
I64_MIN = -9223372036854775808,
3439
}
3540
#[repr(u64)]
41+
#[repr(C)]
3642
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
3743
pub enum MuchULongLong {
3844
MuchHigh = 4294967296,

tests/expectations/tests/enum_in_template_with_typedef.rs

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ 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+
#[repr(C)]
1617
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1718
pub enum std_fbstring_core_Category {
1819
Foo = 0,

tests/expectations/tests/enum_negative.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66

77
#[repr(i32)]
8+
#[repr(C)]
89
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
910
pub enum Foo {
1011
Bar = -2,

tests/expectations/tests/enum_packed.rs

+3
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,21 @@
55

66

77
#[repr(u8)]
8+
#[repr(C)]
89
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
910
pub enum Foo {
1011
Bar = 0,
1112
Qux = 1,
1213
}
1314
#[repr(i8)]
15+
#[repr(C)]
1416
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
1517
pub enum Neg {
1618
MinusOne = -1,
1719
One = 1,
1820
}
1921
#[repr(u16)]
22+
#[repr(C)]
2023
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
2124
pub enum Bigger {
2225
Much = 255,

tests/expectations/tests/forward-enum-decl.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66

77
#[repr(i32)]
8+
#[repr(C)]
89
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
910
pub enum CSSPseudoClassType {
1011
empty = 0,

tests/expectations/tests/func_ptr_in_struct.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@
44
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
55

66

7+
#[repr(i32)]
8+
#[repr(C)]
79
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
8-
pub enum baz {}
10+
pub enum baz {
11+
__bindgen_cannot_repr_c_on_empty_enum = 0,
12+
}
913
#[repr(C)]
1014
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
1115
pub struct Foo {

tests/expectations/tests/issue-372.rs

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ pub mod root {
7777
}
7878
}
7979
#[repr(u32)]
80+
#[repr(C)]
8081
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
8182
pub enum n {
8283
o = 0,

tests/expectations/tests/issue-410.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ pub mod root {
4040
}
4141
}
4242
}
43+
#[repr(u32)]
44+
#[repr(C)]
4345
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
44-
pub enum JSWhyMagic {}
46+
pub enum JSWhyMagic {
47+
__bindgen_cannot_repr_c_on_empty_enum = 0,
48+
}
4549
}

tests/expectations/tests/issue-493.rs

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ impl Default for basic_string___long {
7070
pub const basic_string___min_cap: basic_string__bindgen_ty_1 =
7171
basic_string__bindgen_ty_1::__min_cap;
7272
#[repr(i32)]
73+
#[repr(C)]
7374
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
7475
pub enum basic_string__bindgen_ty_1 {
7576
__min_cap = 0,
@@ -109,6 +110,7 @@ impl Default for basic_string___ulx {
109110
pub const basic_string___n_words: basic_string__bindgen_ty_2 =
110111
basic_string__bindgen_ty_2::__n_words;
111112
#[repr(i32)]
113+
#[repr(C)]
112114
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
113115
pub enum basic_string__bindgen_ty_2 {
114116
__n_words = 0,

0 commit comments

Comments
 (0)