Repository: rust-lang/rust-bindgen
Pull request #2497 (2023-04-10 21:43:50)

 Do not return when calling void functions 
Update the code generation for the `--wrap-static-fns` feature so the wrapper for a static function that returns `void` no longer contains a `return` statement and only calls the function instead.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index aea2e321..bbd4f198 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -167,6 +167,8 @@
 ## Added
 
 ## Changed
+* Wrappers for static functions that return `void` no longer contain a `return`
+  statement and only call the static function instead.
    
 ## Removed
 
diff --git a/bindgen/codegen/serialize.rs b/bindgen/codegen/serialize.rs
index ac620235..0baa70a8 100644
--- a/bindgen/codegen/serialize.rs
+++ b/bindgen/codegen/serialize.rs
@@ -102,14 +102,31 @@ impl<'a> CSerialize<'a> for Function {
 
         // The name used for the wrapper self.
         let wrap_name = format!("{}{}", name, ctx.wrap_static_fns_suffix());
+
         // The function's return type
-        let ret_ty = signature.return_type();
+        let ret_ty = {
+            let type_id = signature.return_type();
+            let item = ctx.resolve_item(type_id);
+            let ret_ty = item.expect_type();
+
+            // Write `ret_ty`.
+            ret_ty.serialize(ctx, item, stack, writer)?;
+
+            ret_ty
+        };
 
-        // Write `ret_ty wrap_name(args) { return name(arg_names)' }`
-        ret_ty.serialize(ctx, (), stack, writer)?;
+        // Write `wrap_name(args`.
         write!(writer, " {}(", wrap_name)?;
         serialize_args(&args, ctx, writer)?;
-        write!(writer, ") {{ return {}(", name)?;
+
+        // Write `) { name(` if the function returns void and `) { return name(` if it does not.
+        if ret_ty.is_void() {
+            write!(writer, ") {{ {}(", name)?;
+        } else {
+            write!(writer, ") {{ return {}(", name)?;
+        }
+
+        // Write `arg_names); }`.
         serialize_sep(", ", args.iter(), ctx, writer, |(name, _), _, buf| {
             write!(buf, "{}", name).map_err(From::from)
         })?;
diff --git a/bindgen/ir/ty.rs b/bindgen/ir/ty.rs
index 8c505aa4..572d7de4 100644
--- a/bindgen/ir/ty.rs
+++ b/bindgen/ir/ty.rs
@@ -124,6 +124,10 @@ impl Type {
         matches!(self.kind, TypeKind::Enum(..))
     }
 
+    /// Is this void?
+    pub(crate) fn is_void(&self) -> bool {
+        matches!(self.kind, TypeKind::Void)
+    }
     /// Is this either a builtin or named type?
     pub(crate) fn is_builtin_or_type_param(&self) -> bool {
         matches!(


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 abc52242..8d6e97aa 100644
--- a/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c
+++ b/bindgen-tests/tests/expectations/tests/generated/wrap_static_fns.c
@@ -10,3 +10,4 @@ int takes_fn__extern(int (f) (int)) { return takes_fn(f); }
 int takes_alias__extern(func f) { return takes_alias(f); }
 int takes_qualified__extern(const int *const *arg) { return takes_qualified(arg); }
 enum foo takes_enum__extern(const enum foo f) { return takes_enum(f); }
+void nevermore__extern(void) { nevermore(); }
diff --git a/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs b/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs
index 0db78054..2800d703 100644
--- a/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs
+++ b/bindgen-tests/tests/expectations/tests/wrap-static-fns.rs
@@ -56,3 +56,7 @@ extern "C" {
     #[link_name = "takes_enum__extern"]
     pub fn takes_enum(f: foo) -> foo;
 }
+extern "C" {
+    #[link_name = "nevermore__extern"]
+    pub fn nevermore();
+}
diff --git a/bindgen-tests/tests/headers/wrap-static-fns.h b/bindgen-tests/tests/headers/wrap-static-fns.h
index faa7b7f1..4a1862b0 100644
--- a/bindgen-tests/tests/headers/wrap-static-fns.h
+++ b/bindgen-tests/tests/headers/wrap-static-fns.h
@@ -40,3 +40,7 @@ enum foo {
 static inline enum foo takes_enum(const enum foo f) {
     return f;
 }
+
+static inline void nevermore() {
+    while (1) { }
+}