Repository: rust-lang/rust-bindgen
Pull request #2415 (2023-02-14 15:17:02)

Add support for enums with the wrapped static functions feature
This PR adds support for enums with the wrapped static functions feature.

I ran the experimental feature on a fairly large C project and got a crash with "Cannot serialize type kind enum"... so I fixed it and test it. Works as expected.


Patch:
diff --git a/bindgen/codegen/serialize.rs b/bindgen/codegen/serialize.rs
index e521c703..13106484 100644
--- a/bindgen/codegen/serialize.rs
+++ b/bindgen/codegen/serialize.rs
@@ -311,6 +311,14 @@ impl<'a> CSerialize<'a> for Type {
                     CompKind::Union => write!(writer, "union {}", name)?,
                 };
             }
+            TypeKind::Enum(_enum_ty) => {
+                if self.is_const() {
+                    write!(writer, "const ")?;
+                }
+
+                let name = item.canonical_name(ctx);
+                write!(writer, "enum {}", name)?;
+            }
             ty => {
                 return Err(CodegenError::Serialize {
                     msg: format!("Cannot serialize type kind {:?}", ty),
diff --git a/book/src/using-bitfields.md b/book/src/using-bitfields.md
index 41e07ad7..0ee9f032 100644
--- a/book/src/using-bitfields.md
+++ b/book/src/using-bitfields.md
@@ -5,7 +5,7 @@
 As Rust does not support bitfields, Bindgen generates a struct for each with the following characteristics
 * Immutable getter functions for each bitfield named ```<bitfield>```
 * Setter functions for each contiguous block of bitfields named ```set_<bitfield>```
-* Far each contiguous block of bitfields, Bindgen emits an opaque physical field that contains one or more logical bitfields
+* For each contiguous block of bitfields, Bindgen emits an opaque physical field that contains one or more logical bitfields
 * A static constructor  ```new_bitfield_{1, 2, ...}``` with a parameter for each bitfield contained within the opaque physical field.
 
 ## Bitfield examples


Test patch:
diff --git a/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c b/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c
index 22b2f67f..f5f33f84 100644
--- a/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c
+++ b/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c
@@ -12,3 +12,5 @@ int takes_alias__extern(func f) asm("takes_alias__extern");
 int takes_alias__extern(func f) { return takes_alias(f); }
 int takes_qualified__extern(const int *const *arg) asm("takes_qualified__extern");
 int takes_qualified__extern(const int *const *arg) { return takes_qualified(arg); }
+enum foo takes_enum__extern(const enum foo f) asm("takes_enum__extern");
+enum foo takes_enum__extern(const enum foo f) { return takes_enum(f); }
diff --git a/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs b/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs
index 54ed9fd4..fbfdcb13 100644
--- a/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs
+++ b/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs
@@ -50,3 +50,9 @@ extern "C" {
         arg: *const *const ::std::os::raw::c_int,
     ) -> ::std::os::raw::c_int;
 }
+pub const foo_BAR: foo = 0;
+pub type foo = ::std::os::raw::c_uint;
+extern "C" {
+    #[link_name = "\u{1}takes_enum__extern"]
+    pub fn takes_enum(f: foo) -> foo;
+}
diff --git a/bindgen-tests/tests/headers/wrap-static-fns.h b/bindgen-tests/tests/headers/wrap-static-fns.h
index 8b90c7bc..03892315 100644
--- a/bindgen-tests/tests/headers/wrap-static-fns.h
+++ b/bindgen-tests/tests/headers/wrap-static-fns.h
@@ -31,3 +31,11 @@ static inline int takes_alias(func f) {
 static inline int takes_qualified(const int *const *arg) {
     return **arg;
 }
+
+enum foo {
+    BAR = 0x0,
+};
+
+static inline enum foo takes_enum(const enum foo f) {
+    return f;
+}