diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2023-01-06 19:07:28 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-06 13:07:28 -0500 |
commit | 5875949e8e598fa9b0e3a018b3547815e2654fc8 (patch) | |
tree | 51e136ee161b86d3b71fbb3934d7f708b0b9c29f | |
parent | 1abaf7ebbfee423ec524bd6e3b13f626cf32bc69 (diff) |
codegen: Look through typedefs to detect void return type. (#2379)
* codegen: Look through typedefs to detect void return type.
And reuse a bit more code.
Should fix #2377, but needs a test (can't run tests atm).
* Add tests
* Run rustfmt
* Update changelog
Co-authored-by: Christian Poveda <christian.poveda@ferrous-systems.com>
-rw-r--r-- | CHANGELOG.md | 3 | ||||
-rw-r--r-- | bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs | 2 | ||||
-rw-r--r-- | bindgen-tests/tests/expectations/tests/void_typedef.rs | 18 | ||||
-rw-r--r-- | bindgen-tests/tests/headers/void_typedef.h | 9 | ||||
-rw-r--r-- | bindgen/codegen/dyngen.rs | 2 | ||||
-rw-r--r-- | bindgen/codegen/mod.rs | 62 |
6 files changed, 71 insertions, 25 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 144805d1..322e65de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -159,7 +159,8 @@ * The `ParseCallbacks::generated_name_override` now receives `ItemInfo<'_>` as argument instead of a `&str`. * Updated the `clang-sys` crate version to 1.4.0 to support clang 15. - + * The return type is now ommited in signatures of functions returning `void`. + ## Removed ## Fixed diff --git a/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs index 514cff73..098ffa24 100644 --- a/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs +++ b/bindgen-tests/tests/expectations/tests/dynamic_loading_with_class.rs @@ -99,7 +99,7 @@ impl TestLib { ) -> ::std::os::raw::c_int { (self.foo.as_ref().expect("Expected function, got error."))(x) } - pub unsafe fn bar(&self) -> () { + pub unsafe fn bar(&self) { (self.bar.as_ref().expect("Expected function, got error."))() } } diff --git a/bindgen-tests/tests/expectations/tests/void_typedef.rs b/bindgen-tests/tests/expectations/tests/void_typedef.rs new file mode 100644 index 00000000..7e148e72 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/void_typedef.rs @@ -0,0 +1,18 @@ +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +pub type VOID = ::std::os::raw::c_void; +pub type ALSO_VOID = VOID; +extern "C" { + pub fn this_api_returns_nothing(); +} +extern "C" { + pub fn this_api_also_returns_nothing(); +} +extern "C" { + pub fn this_other_api_also_returns_nothing(); +} diff --git a/bindgen-tests/tests/headers/void_typedef.h b/bindgen-tests/tests/headers/void_typedef.h new file mode 100644 index 00000000..405cbd0c --- /dev/null +++ b/bindgen-tests/tests/headers/void_typedef.h @@ -0,0 +1,9 @@ +typedef void VOID; + +typedef VOID ALSO_VOID; + +void this_api_returns_nothing(void); + +VOID this_api_also_returns_nothing(VOID); + +ALSO_VOID this_other_api_also_returns_nothing(ALSO_VOID); diff --git a/bindgen/codegen/dyngen.rs b/bindgen/codegen/dyngen.rs index 5e734ccd..d8ea8117 100644 --- a/bindgen/codegen/dyngen.rs +++ b/bindgen/codegen/dyngen.rs @@ -170,7 +170,7 @@ impl DynamicItems { if !is_variadic { self.struct_implementation.push(quote! { #(#attributes)* - pub unsafe fn #ident ( &self, #( #args ),* ) -> #ret_ty { + pub unsafe fn #ident ( &self, #( #args ),* ) #ret_ty { #call_body } }); diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs index c297aaab..041d3669 100644 --- a/bindgen/codegen/mod.rs +++ b/bindgen/codegen/mod.rs @@ -4135,11 +4135,7 @@ impl CodeGenerator for Function { if is_dynamic_function { let args_identifiers = utils::fnsig_argument_identifiers(ctx, signature); - let return_item = ctx.resolve_item(signature.return_type()); - let ret_ty = match *return_item.kind().expect_type().kind() { - TypeKind::Void => quote! {()}, - _ => return_item.to_rust_ty_or_opaque(ctx, &()), - }; + let ret_ty = utils::fnsig_return_ty(ctx, signature); result.dynamic_items().push( ident, abi, @@ -4811,25 +4807,52 @@ pub mod utils { }) } - pub fn fnsig_return_ty( + fn fnsig_return_ty_internal( ctx: &BindgenContext, sig: &FunctionSig, + include_arrow: bool, ) -> proc_macro2::TokenStream { if sig.is_divergent() { - return quote! { -> ! }; + return if include_arrow { + quote! { -> ! } + } else { + quote! { ! } + }; } - let return_item = ctx.resolve_item(sig.return_type()); - if let TypeKind::Void = *return_item.kind().expect_type().kind() { - quote! {} + let canonical_type_kind = sig + .return_type() + .into_resolver() + .through_type_refs() + .through_type_aliases() + .resolve(ctx) + .kind() + .expect_type() + .kind(); + + if let TypeKind::Void = canonical_type_kind { + return if include_arrow { + quote! {} + } else { + quote! { () } + }; + } + + let ret_ty = sig.return_type().to_rust_ty_or_opaque(ctx, &()); + if include_arrow { + quote! { -> #ret_ty } } else { - let ret_ty = return_item.to_rust_ty_or_opaque(ctx, &()); - quote! { - -> #ret_ty - } + ret_ty } } + pub fn fnsig_return_ty( + ctx: &BindgenContext, + sig: &FunctionSig, + ) -> proc_macro2::TokenStream { + fnsig_return_ty_internal(ctx, sig, /* include_arrow = */ true) + } + pub fn fnsig_arguments( ctx: &BindgenContext, sig: &FunctionSig, @@ -4942,14 +4965,9 @@ pub mod utils { arg_item.to_rust_ty_or_opaque(ctx, &()) }); - let return_item = ctx.resolve_item(sig.return_type()); - let ret_ty = - if let TypeKind::Void = *return_item.kind().expect_type().kind() { - quote! { () } - } else { - return_item.to_rust_ty_or_opaque(ctx, &()) - }; - + let ret_ty = fnsig_return_ty_internal( + ctx, sig, /* include_arrow = */ false, + ); quote! { *const ::block::Block<(#(#args,)*), #ret_ty> } |