From 89b43dc6297cc44b909455ef742cd5754ad2f9c1 Mon Sep 17 00:00:00 2001 From: Konrad Koschel Date: Wed, 30 Jul 2025 16:00:01 +0200 Subject: [PATCH 1/3] feat: Implement support for link type 'raw-dylib' on Windows --- .../tests/windows-raw-dylib-verbatim.rs | 5 ++++ .../expectations/tests/windows-raw-dylib.rs | 5 ++++ .../headers/windows-raw-dylib-verbatim.h | 3 ++ .../tests/headers/windows-raw-dylib.h | 3 ++ bindgen/codegen/mod.rs | 24 ++++++++++++---- bindgen/options/cli.rs | 15 ++++++++++ bindgen/options/mod.rs | 28 +++++++++++++++++++ 7 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 bindgen-tests/tests/expectations/tests/windows-raw-dylib-verbatim.rs create mode 100644 bindgen-tests/tests/expectations/tests/windows-raw-dylib.rs create mode 100644 bindgen-tests/tests/headers/windows-raw-dylib-verbatim.h create mode 100644 bindgen-tests/tests/headers/windows-raw-dylib.h diff --git a/bindgen-tests/tests/expectations/tests/windows-raw-dylib-verbatim.rs b/bindgen-tests/tests/expectations/tests/windows-raw-dylib-verbatim.rs new file mode 100644 index 0000000000..d2247e3523 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/windows-raw-dylib-verbatim.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[cfg_attr(windows, link(name = "foo.exe", kind = "raw-dylib", modifiers = "+verbatim"))] +unsafe extern "C" { + pub fn test_function(); +} diff --git a/bindgen-tests/tests/expectations/tests/windows-raw-dylib.rs b/bindgen-tests/tests/expectations/tests/windows-raw-dylib.rs new file mode 100644 index 0000000000..602d82b053 --- /dev/null +++ b/bindgen-tests/tests/expectations/tests/windows-raw-dylib.rs @@ -0,0 +1,5 @@ +#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)] +#[cfg_attr(windows, link(name = "foolib", kind = "raw-dylib"))] +unsafe extern "C" { + pub fn test_function(); +} diff --git a/bindgen-tests/tests/headers/windows-raw-dylib-verbatim.h b/bindgen-tests/tests/headers/windows-raw-dylib-verbatim.h new file mode 100644 index 0000000000..394b275b37 --- /dev/null +++ b/bindgen-tests/tests/headers/windows-raw-dylib-verbatim.h @@ -0,0 +1,3 @@ +// bindgen-flags: --windows-link-as-raw-dylib foo.exe --windows-link-as-raw-dylib-verbatim + +void test_function(); \ No newline at end of file diff --git a/bindgen-tests/tests/headers/windows-raw-dylib.h b/bindgen-tests/tests/headers/windows-raw-dylib.h new file mode 100644 index 0000000000..14c771540c --- /dev/null +++ b/bindgen-tests/tests/headers/windows-raw-dylib.h @@ -0,0 +1,3 @@ +// bindgen-flags: --windows-link-as-raw-dylib foolib + +void test_function(); \ No newline at end of file diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs index 5425962bac..04f278299a 100644 --- a/bindgen/codegen/mod.rs +++ b/bindgen/codegen/mod.rs @@ -4717,10 +4717,24 @@ impl CodeGenerator for Function { // Unfortunately this can't piggyback on the `attributes` list because // the #[link(wasm_import_module)] needs to happen before the `extern // "C"` block. It doesn't get picked up properly otherwise - let wasm_link_attribute = - ctx.options().wasm_import_module_name.as_ref().map(|name| { - quote! { #[link(wasm_import_module = #name)] } - }); + let link_attribute = match ( + ctx.options().wasm_import_module_name.as_ref(), + &ctx.options().windows_link_as_raw_dylib, + ) { + (Some(_), (Some(_), _)) => { + panic!("Cannot link against a wasm import module and a raw dylib at the same time"); + } + (Some(name), (None, _)) => { + Some(quote! { #[link(wasm_import_module = #name)] }) + } + (None, (Some(name), false)) => Some( + quote! { #[cfg_attr(windows, link(name = #name, kind = "raw-dylib"))] }, + ), + (None, (Some(name), true)) => Some( + quote! { #[cfg_attr(windows, link(name = #name, kind = "raw-dylib", modifiers = "+verbatim"))] }, + ), + _ => None, + }; let should_wrap = is_internal && ctx.options().wrap_static_fns && @@ -4774,7 +4788,7 @@ impl CodeGenerator for Function { .then(|| quote!(unsafe)); let tokens = quote! { - #wasm_link_attribute + #link_attribute #safety extern #abi { #(#attributes)* pub fn #ident ( #( #args ),* ) #ret; diff --git a/bindgen/options/cli.rs b/bindgen/options/cli.rs index bce7faed35..e2221e1080 100644 --- a/bindgen/options/cli.rs +++ b/bindgen/options/cli.rs @@ -420,6 +420,12 @@ struct BindgenCommand { /// The NAME to be used in a #[link(wasm_import_module = ...)] statement #[arg(long, value_name = "NAME")] wasm_import_module_name: Option, + /// On Windows, link against NAME with kind `raw-dylib`. + #[arg(long, value_name = "NAME")] + windows_link_as_raw_dylib: Option, + /// Do not append `.dll` suffix to the NAME provided to `--windows-link-as-raw-dylib`. + #[arg(long, requires = "windows_link_as_raw_dylib")] + windows_link_as_raw_dylib_verbatim: bool, /// Use dynamic loading mode with the given library NAME. #[arg(long, value_name = "NAME")] dynamic_loading: Option, @@ -643,6 +649,8 @@ where enable_function_attribute_detection, use_array_pointers_in_arguments, wasm_import_module_name, + windows_link_as_raw_dylib, + windows_link_as_raw_dylib_verbatim, dynamic_loading, dynamic_link_require_all, prefix_link_name, @@ -1083,6 +1091,13 @@ where builder = builder.emit_diagnostics(); } + if let Some(windows_link_as_raw_dylib) = windows_link_as_raw_dylib { + builder = builder.windows_link_as_raw_dylib( + windows_link_as_raw_dylib, + windows_link_as_raw_dylib_verbatim, + ); + } + Ok((builder, output, verbose)) } diff --git a/bindgen/options/mod.rs b/bindgen/options/mod.rs index b876b4d5b3..c2c53c4776 100644 --- a/bindgen/options/mod.rs +++ b/bindgen/options/mod.rs @@ -1908,6 +1908,34 @@ options! { }, as_args: "--wasm-import-module-name", }, + /// On Windows, link with kind `raw-dylib` + windows_link_as_raw_dylib: (Option, bool) { + methods: { + /// Adds the `#[cfg_attr(windows, link(name = "", kind = "raw-dylib"))]` attribute to all the `extern` + /// blocks generated by `bindgen`. + /// + /// This attribute is not added by default. + /// + /// If `verbatim` is set to `true`, instead `#[cfg_attr(windows, link(name = "", kind = "raw-dylib", modifiers = "+verbatim"))]` is used. + pub fn windows_link_as_raw_dylib>( + mut self, + dylib: T, + verbatim: bool, + ) -> Self { + self.options.windows_link_as_raw_dylib = (Some(dylib.into()), verbatim); + self + } + }, + as_args: |(dylib, verbatim), args| { + if let Some(dylib) = dylib { + args.push("--windows-link-as-raw-dylib".to_owned()); + args.push(dylib.into()); + if *verbatim { + args.push("--windows-link-as-raw-dylib-verbatim".to_owned()); + } + } + }, + }, /// The name of the dynamic library (if we are generating bindings for a shared library). dynamic_library_name: Option { methods: { From ab95fd0bc337b1a55639b01891ecd56f4c569aca Mon Sep 17 00:00:00 2001 From: Konrad Koschel Date: Mon, 18 Aug 2025 14:19:33 +0200 Subject: [PATCH 2/3] chore: allow both wasm_import and raw-dylib --- bindgen/codegen/mod.rs | 220 +++++++++++++++++++++-------------------- 1 file changed, 111 insertions(+), 109 deletions(-) diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs index 04f278299a..6e6e875812 100644 --- a/bindgen/codegen/mod.rs +++ b/bindgen/codegen/mod.rs @@ -429,21 +429,21 @@ impl WithImplicitTemplateParams for syn::Type { unreachable!("we resolved item through type refs") } // None of these types ever have implicit template parameters. - TypeKind::Void | - TypeKind::NullPtr | - TypeKind::Pointer(..) | - TypeKind::Reference(..) | - TypeKind::Int(..) | - TypeKind::Float(..) | - TypeKind::Complex(..) | - TypeKind::Array(..) | - TypeKind::TypeParam | - TypeKind::Opaque | - TypeKind::Function(..) | - TypeKind::Enum(..) | - TypeKind::ObjCId | - TypeKind::ObjCSel | - TypeKind::TemplateInstantiation(..) => None, + TypeKind::Void + | TypeKind::NullPtr + | TypeKind::Pointer(..) + | TypeKind::Reference(..) + | TypeKind::Int(..) + | TypeKind::Float(..) + | TypeKind::Complex(..) + | TypeKind::Array(..) + | TypeKind::TypeParam + | TypeKind::Opaque + | TypeKind::Function(..) + | TypeKind::Enum(..) + | TypeKind::ObjCId + | TypeKind::ObjCSel + | TypeKind::TemplateInstantiation(..) => None, _ => { let params = item.used_template_params(ctx); if params.is_empty() { @@ -592,9 +592,9 @@ impl CodeGenerator for Module { } }; - if !ctx.options().enable_cxx_namespaces || - (self.is_inline() && - !ctx.options().conservative_inline_namespaces) + if !ctx.options().enable_cxx_namespaces + || (self.is_inline() + && !ctx.options().conservative_inline_namespaces) { codegen_self(result, &mut false); return; @@ -844,19 +844,19 @@ impl CodeGenerator for Type { debug_assert!(item.is_enabled_for_codegen(ctx)); match *self.kind() { - TypeKind::Void | - TypeKind::NullPtr | - TypeKind::Int(..) | - TypeKind::Float(..) | - TypeKind::Complex(..) | - TypeKind::Array(..) | - TypeKind::Vector(..) | - TypeKind::Pointer(..) | - TypeKind::Reference(..) | - TypeKind::Function(..) | - TypeKind::ResolvedTypeRef(..) | - TypeKind::Opaque | - TypeKind::TypeParam => { + TypeKind::Void + | TypeKind::NullPtr + | TypeKind::Int(..) + | TypeKind::Float(..) + | TypeKind::Complex(..) + | TypeKind::Array(..) + | TypeKind::Vector(..) + | TypeKind::Pointer(..) + | TypeKind::Reference(..) + | TypeKind::Function(..) + | TypeKind::ResolvedTypeRef(..) + | TypeKind::Opaque + | TypeKind::TypeParam => { // These items don't need code generation, they only need to be // converted to rust types in fields, arguments, and such. // NOTE(emilio): If you add to this list, make sure to also add @@ -1020,11 +1020,11 @@ impl CodeGenerator for Type { // We prefer using `pub use` over `pub type` because of: // https://github.com/rust-lang/rust/issues/26264 - if matches!(inner_rust_type, syn::Type::Path(_)) && - outer_params.is_empty() && - !is_opaque && - alias_style == AliasVariation::TypeAlias && - inner_item.expect_type().canonical_type(ctx).is_enum() + if matches!(inner_rust_type, syn::Type::Path(_)) + && outer_params.is_empty() + && !is_opaque + && alias_style == AliasVariation::TypeAlias + && inner_item.expect_type().canonical_type(ctx).is_enum() { tokens.append_all(quote! { pub use @@ -1201,9 +1201,9 @@ impl CodeGenerator for Vtable<'_> { // For now, we will only generate vtables for classes that: // - do not inherit from others (compilers merge VTable from primary parent class). // - do not contain a virtual destructor (requires ordering; platforms generate different vtables). - if ctx.options().vtable_generation && - self.comp_info.base_members().is_empty() && - self.comp_info.destructor().is_none() + if ctx.options().vtable_generation + && self.comp_info.base_members().is_empty() + && self.comp_info.destructor().is_none() { let class_ident = ctx.rust_ident(self.item_id.canonical_name(ctx)); @@ -1792,8 +1792,8 @@ impl FieldCodegen<'_> for BitfieldUnit { continue; } - if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT && - !ctx.options().rust_features().larger_arrays + if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT + && !ctx.options().rust_features().larger_arrays { continue; } @@ -2395,10 +2395,10 @@ impl CodeGenerator for CompInfo { // if a type has both a "packed" attribute and an "align(N)" attribute, then check if the // "packed" attr is redundant, and do not include it if so. - if packed && - !is_opaque && - !(explicit_align.is_some() && - self.already_packed(ctx).unwrap_or(false)) + if packed + && !is_opaque + && !(explicit_align.is_some() + && self.already_packed(ctx).unwrap_or(false)) { let n = layout.map_or(1, |l| l.align); assert!(ctx.options().rust_features().repr_packed_n || n == 1); @@ -2439,32 +2439,32 @@ impl CodeGenerator for CompInfo { let derivable_traits = derives_of_item(item, ctx, packed); if !derivable_traits.contains(DerivableTraits::DEBUG) { - needs_debug_impl = ctx.options().derive_debug && - ctx.options().impl_debug && - !ctx.no_debug_by_name(item) && - !item.annotations().disallow_debug(); + needs_debug_impl = ctx.options().derive_debug + && ctx.options().impl_debug + && !ctx.no_debug_by_name(item) + && !item.annotations().disallow_debug(); } if !derivable_traits.contains(DerivableTraits::DEFAULT) { - needs_default_impl = ctx.options().derive_default && - !self.is_forward_declaration() && - !ctx.no_default_by_name(item) && - !item.annotations().disallow_default(); + needs_default_impl = ctx.options().derive_default + && !self.is_forward_declaration() + && !ctx.no_default_by_name(item) + && !item.annotations().disallow_default(); } let all_template_params = item.all_template_params(ctx); - if derivable_traits.contains(DerivableTraits::COPY) && - !derivable_traits.contains(DerivableTraits::CLONE) + if derivable_traits.contains(DerivableTraits::COPY) + && !derivable_traits.contains(DerivableTraits::CLONE) { needs_clone_impl = true; } if !derivable_traits.contains(DerivableTraits::PARTIAL_EQ) { - needs_partialeq_impl = ctx.options().derive_partialeq && - ctx.options().impl_partialeq && - ctx.lookup_can_derive_partialeq_or_partialord(item.id()) == - CanDerive::Manually; + needs_partialeq_impl = ctx.options().derive_partialeq + && ctx.options().impl_partialeq + && ctx.lookup_can_derive_partialeq_or_partialord(item.id()) + == CanDerive::Manually; } let mut derives: Vec<_> = derivable_traits.into(); @@ -2646,8 +2646,8 @@ impl CodeGenerator for CompInfo { .collect() }; - let uninit_decl = if check_field_offset.is_empty() || - compile_time + let uninit_decl = if check_field_offset.is_empty() + || compile_time { None } else { @@ -2993,11 +2993,11 @@ impl Method { let cc = &ctx.options().codegen_config; match self.kind() { MethodKind::Constructor => cc.constructors(), - MethodKind::Destructor | - MethodKind::VirtualDestructor { .. } => cc.destructors(), - MethodKind::Static | - MethodKind::Normal | - MethodKind::Virtual { .. } => cc.methods(), + MethodKind::Destructor + | MethodKind::VirtualDestructor { .. } => cc.destructors(), + MethodKind::Static + | MethodKind::Normal + | MethodKind::Virtual { .. } => cc.methods(), } }); @@ -3517,8 +3517,8 @@ impl EnumBuilder { } variants } - EnumBuilderKind::Consts { .. } | - EnumBuilderKind::ModuleConsts { .. } => { + EnumBuilderKind::Consts { .. } + | EnumBuilderKind::ModuleConsts { .. } => { let mut variants = vec![]; for v in self.enum_variants { @@ -3640,8 +3640,8 @@ impl CodeGenerator for Enum { let repr_translated; let repr = match self.repr().map(|repr| ctx.resolve_type(repr)) { Some(repr) - if !ctx.options().translate_enum_integer_types && - !variation.is_rust() => + if !ctx.options().translate_enum_integer_types + && !variation.is_rust() => { repr } @@ -3712,10 +3712,10 @@ impl CodeGenerator for Enum { // Clone/Eq/PartialEq/Hash, even if we don't generate those by // default. derives.insert( - DerivableTraits::CLONE | - DerivableTraits::HASH | - DerivableTraits::PARTIAL_EQ | - DerivableTraits::EQ, + DerivableTraits::CLONE + | DerivableTraits::HASH + | DerivableTraits::PARTIAL_EQ + | DerivableTraits::EQ, ); let mut derives: Vec<_> = derives.into(); for derive in item.annotations().derives() { @@ -3856,8 +3856,8 @@ impl CodeGenerator for Enum { Entry::Occupied(ref entry) => { if variation.is_rust() { let variant_name = ctx.rust_mangle(variant.name()); - let mangled_name = if is_toplevel || - enum_ty.name().is_some() + let mangled_name = if is_toplevel + || enum_ty.name().is_some() { variant_name } else { @@ -3916,8 +3916,8 @@ impl CodeGenerator for Enum { // If it's an unnamed enum, or constification is enforced, // we also generate a constant so it can be properly // accessed. - if (variation.is_rust() && enum_ty.name().is_none()) || - variant.force_constification() + if (variation.is_rust() && enum_ty.name().is_none()) + || variant.force_constification() { let mangled_name = if is_toplevel { variant_name.clone() @@ -4360,16 +4360,17 @@ impl TryToRustTy for Type { inst.try_to_rust_ty(ctx, item) } TypeKind::ResolvedTypeRef(inner) => inner.try_to_rust_ty(ctx, &()), - TypeKind::TemplateAlias(..) | - TypeKind::Alias(..) | - TypeKind::BlockPointer(..) => { + TypeKind::TemplateAlias(..) + | TypeKind::Alias(..) + | TypeKind::BlockPointer(..) => { if self.is_block_pointer() && !ctx.options().generate_block { let void = c_void(ctx); return Ok(void.to_ptr(/* is_const = */ false)); } - if item.is_opaque(ctx, &()) && - item.used_template_params(ctx) + if item.is_opaque(ctx, &()) + && item + .used_template_params(ctx) .into_iter() .any(|param| param.is_template_param(ctx, &())) { @@ -4385,8 +4386,8 @@ impl TryToRustTy for Type { } TypeKind::Comp(ref info) => { let template_params = item.all_template_params(ctx); - if info.has_non_type_template_params() || - (item.is_opaque(ctx, &()) && !template_params.is_empty()) + if info.has_non_type_template_params() + || (item.is_opaque(ctx, &()) && !template_params.is_empty()) { return self.try_to_opaque(ctx, item); } @@ -4717,28 +4718,29 @@ impl CodeGenerator for Function { // Unfortunately this can't piggyback on the `attributes` list because // the #[link(wasm_import_module)] needs to happen before the `extern // "C"` block. It doesn't get picked up properly otherwise - let link_attribute = match ( - ctx.options().wasm_import_module_name.as_ref(), - &ctx.options().windows_link_as_raw_dylib, - ) { - (Some(_), (Some(_), _)) => { - panic!("Cannot link against a wasm import module and a raw dylib at the same time"); - } - (Some(name), (None, _)) => { - Some(quote! { #[link(wasm_import_module = #name)] }) + let mut link_attribute = quote! {}; + if let Some(ref wasm_name) = ctx.options().wasm_import_module_name { + link_attribute.extend(quote! { + #[link(wasm_import_module = #wasm_name)] + }); + } + if let (Some(ref windows_name), verbatim) = + ctx.options().windows_link_as_raw_dylib + { + if verbatim { + link_attribute.extend(quote! { + #[cfg_attr(windows, link(name = #windows_name, kind = "raw-dylib", modifiers = "+verbatim"))] + }); + } else { + link_attribute.extend(quote! { + #[cfg_attr(windows, link(name = #windows_name, kind = "raw-dylib"))] + }); } - (None, (Some(name), false)) => Some( - quote! { #[cfg_attr(windows, link(name = #name, kind = "raw-dylib"))] }, - ), - (None, (Some(name), true)) => Some( - quote! { #[cfg_attr(windows, link(name = #name, kind = "raw-dylib", modifiers = "+verbatim"))] }, - ), - _ => None, - }; + } - let should_wrap = is_internal && - ctx.options().wrap_static_fns && - link_name_attr.is_none(); + let should_wrap = is_internal + && ctx.options().wrap_static_fns + && link_name_attr.is_none(); if should_wrap { let name = canonical_name.clone() + ctx.wrap_static_fns_suffix(); @@ -5282,8 +5284,8 @@ pub(crate) mod utils { std::fs::create_dir_all(dir)?; } - let is_cpp = args_are_cpp(&context.options().clang_args) || - context + let is_cpp = args_are_cpp(&context.options().clang_args) + || context .options() .input_headers .iter() @@ -5381,8 +5383,8 @@ pub(crate) mod utils { ctx: &BindgenContext, result: &mut Vec, ) { - if ctx.options().blocklisted_items.matches(BITFIELD_UNIT) || - ctx.options().blocklisted_types.matches(BITFIELD_UNIT) + if ctx.options().blocklisted_items.matches(BITFIELD_UNIT) + || ctx.options().blocklisted_types.matches(BITFIELD_UNIT) { return; } From 6d1c15e2c937eff833604eeba343ac62bc9f65ad Mon Sep 17 00:00:00 2001 From: Konrad Koschel Date: Mon, 18 Aug 2025 14:22:21 +0200 Subject: [PATCH 3/3] chore: cargo fmt --- bindgen/codegen/mod.rs | 185 ++++++++++++++++++++--------------------- 1 file changed, 92 insertions(+), 93 deletions(-) diff --git a/bindgen/codegen/mod.rs b/bindgen/codegen/mod.rs index 6e6e875812..3326168583 100644 --- a/bindgen/codegen/mod.rs +++ b/bindgen/codegen/mod.rs @@ -429,21 +429,21 @@ impl WithImplicitTemplateParams for syn::Type { unreachable!("we resolved item through type refs") } // None of these types ever have implicit template parameters. - TypeKind::Void - | TypeKind::NullPtr - | TypeKind::Pointer(..) - | TypeKind::Reference(..) - | TypeKind::Int(..) - | TypeKind::Float(..) - | TypeKind::Complex(..) - | TypeKind::Array(..) - | TypeKind::TypeParam - | TypeKind::Opaque - | TypeKind::Function(..) - | TypeKind::Enum(..) - | TypeKind::ObjCId - | TypeKind::ObjCSel - | TypeKind::TemplateInstantiation(..) => None, + TypeKind::Void | + TypeKind::NullPtr | + TypeKind::Pointer(..) | + TypeKind::Reference(..) | + TypeKind::Int(..) | + TypeKind::Float(..) | + TypeKind::Complex(..) | + TypeKind::Array(..) | + TypeKind::TypeParam | + TypeKind::Opaque | + TypeKind::Function(..) | + TypeKind::Enum(..) | + TypeKind::ObjCId | + TypeKind::ObjCSel | + TypeKind::TemplateInstantiation(..) => None, _ => { let params = item.used_template_params(ctx); if params.is_empty() { @@ -592,9 +592,9 @@ impl CodeGenerator for Module { } }; - if !ctx.options().enable_cxx_namespaces - || (self.is_inline() - && !ctx.options().conservative_inline_namespaces) + if !ctx.options().enable_cxx_namespaces || + (self.is_inline() && + !ctx.options().conservative_inline_namespaces) { codegen_self(result, &mut false); return; @@ -844,19 +844,19 @@ impl CodeGenerator for Type { debug_assert!(item.is_enabled_for_codegen(ctx)); match *self.kind() { - TypeKind::Void - | TypeKind::NullPtr - | TypeKind::Int(..) - | TypeKind::Float(..) - | TypeKind::Complex(..) - | TypeKind::Array(..) - | TypeKind::Vector(..) - | TypeKind::Pointer(..) - | TypeKind::Reference(..) - | TypeKind::Function(..) - | TypeKind::ResolvedTypeRef(..) - | TypeKind::Opaque - | TypeKind::TypeParam => { + TypeKind::Void | + TypeKind::NullPtr | + TypeKind::Int(..) | + TypeKind::Float(..) | + TypeKind::Complex(..) | + TypeKind::Array(..) | + TypeKind::Vector(..) | + TypeKind::Pointer(..) | + TypeKind::Reference(..) | + TypeKind::Function(..) | + TypeKind::ResolvedTypeRef(..) | + TypeKind::Opaque | + TypeKind::TypeParam => { // These items don't need code generation, they only need to be // converted to rust types in fields, arguments, and such. // NOTE(emilio): If you add to this list, make sure to also add @@ -1020,11 +1020,11 @@ impl CodeGenerator for Type { // We prefer using `pub use` over `pub type` because of: // https://github.com/rust-lang/rust/issues/26264 - if matches!(inner_rust_type, syn::Type::Path(_)) - && outer_params.is_empty() - && !is_opaque - && alias_style == AliasVariation::TypeAlias - && inner_item.expect_type().canonical_type(ctx).is_enum() + if matches!(inner_rust_type, syn::Type::Path(_)) && + outer_params.is_empty() && + !is_opaque && + alias_style == AliasVariation::TypeAlias && + inner_item.expect_type().canonical_type(ctx).is_enum() { tokens.append_all(quote! { pub use @@ -1201,9 +1201,9 @@ impl CodeGenerator for Vtable<'_> { // For now, we will only generate vtables for classes that: // - do not inherit from others (compilers merge VTable from primary parent class). // - do not contain a virtual destructor (requires ordering; platforms generate different vtables). - if ctx.options().vtable_generation - && self.comp_info.base_members().is_empty() - && self.comp_info.destructor().is_none() + if ctx.options().vtable_generation && + self.comp_info.base_members().is_empty() && + self.comp_info.destructor().is_none() { let class_ident = ctx.rust_ident(self.item_id.canonical_name(ctx)); @@ -1792,8 +1792,8 @@ impl FieldCodegen<'_> for BitfieldUnit { continue; } - if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT - && !ctx.options().rust_features().larger_arrays + if layout.size > RUST_DERIVE_IN_ARRAY_LIMIT && + !ctx.options().rust_features().larger_arrays { continue; } @@ -2395,10 +2395,10 @@ impl CodeGenerator for CompInfo { // if a type has both a "packed" attribute and an "align(N)" attribute, then check if the // "packed" attr is redundant, and do not include it if so. - if packed - && !is_opaque - && !(explicit_align.is_some() - && self.already_packed(ctx).unwrap_or(false)) + if packed && + !is_opaque && + !(explicit_align.is_some() && + self.already_packed(ctx).unwrap_or(false)) { let n = layout.map_or(1, |l| l.align); assert!(ctx.options().rust_features().repr_packed_n || n == 1); @@ -2439,32 +2439,32 @@ impl CodeGenerator for CompInfo { let derivable_traits = derives_of_item(item, ctx, packed); if !derivable_traits.contains(DerivableTraits::DEBUG) { - needs_debug_impl = ctx.options().derive_debug - && ctx.options().impl_debug - && !ctx.no_debug_by_name(item) - && !item.annotations().disallow_debug(); + needs_debug_impl = ctx.options().derive_debug && + ctx.options().impl_debug && + !ctx.no_debug_by_name(item) && + !item.annotations().disallow_debug(); } if !derivable_traits.contains(DerivableTraits::DEFAULT) { - needs_default_impl = ctx.options().derive_default - && !self.is_forward_declaration() - && !ctx.no_default_by_name(item) - && !item.annotations().disallow_default(); + needs_default_impl = ctx.options().derive_default && + !self.is_forward_declaration() && + !ctx.no_default_by_name(item) && + !item.annotations().disallow_default(); } let all_template_params = item.all_template_params(ctx); - if derivable_traits.contains(DerivableTraits::COPY) - && !derivable_traits.contains(DerivableTraits::CLONE) + if derivable_traits.contains(DerivableTraits::COPY) && + !derivable_traits.contains(DerivableTraits::CLONE) { needs_clone_impl = true; } if !derivable_traits.contains(DerivableTraits::PARTIAL_EQ) { - needs_partialeq_impl = ctx.options().derive_partialeq - && ctx.options().impl_partialeq - && ctx.lookup_can_derive_partialeq_or_partialord(item.id()) - == CanDerive::Manually; + needs_partialeq_impl = ctx.options().derive_partialeq && + ctx.options().impl_partialeq && + ctx.lookup_can_derive_partialeq_or_partialord(item.id()) == + CanDerive::Manually; } let mut derives: Vec<_> = derivable_traits.into(); @@ -2646,8 +2646,8 @@ impl CodeGenerator for CompInfo { .collect() }; - let uninit_decl = if check_field_offset.is_empty() - || compile_time + let uninit_decl = if check_field_offset.is_empty() || + compile_time { None } else { @@ -2993,11 +2993,11 @@ impl Method { let cc = &ctx.options().codegen_config; match self.kind() { MethodKind::Constructor => cc.constructors(), - MethodKind::Destructor - | MethodKind::VirtualDestructor { .. } => cc.destructors(), - MethodKind::Static - | MethodKind::Normal - | MethodKind::Virtual { .. } => cc.methods(), + MethodKind::Destructor | + MethodKind::VirtualDestructor { .. } => cc.destructors(), + MethodKind::Static | + MethodKind::Normal | + MethodKind::Virtual { .. } => cc.methods(), } }); @@ -3517,8 +3517,8 @@ impl EnumBuilder { } variants } - EnumBuilderKind::Consts { .. } - | EnumBuilderKind::ModuleConsts { .. } => { + EnumBuilderKind::Consts { .. } | + EnumBuilderKind::ModuleConsts { .. } => { let mut variants = vec![]; for v in self.enum_variants { @@ -3640,8 +3640,8 @@ impl CodeGenerator for Enum { let repr_translated; let repr = match self.repr().map(|repr| ctx.resolve_type(repr)) { Some(repr) - if !ctx.options().translate_enum_integer_types - && !variation.is_rust() => + if !ctx.options().translate_enum_integer_types && + !variation.is_rust() => { repr } @@ -3712,10 +3712,10 @@ impl CodeGenerator for Enum { // Clone/Eq/PartialEq/Hash, even if we don't generate those by // default. derives.insert( - DerivableTraits::CLONE - | DerivableTraits::HASH - | DerivableTraits::PARTIAL_EQ - | DerivableTraits::EQ, + DerivableTraits::CLONE | + DerivableTraits::HASH | + DerivableTraits::PARTIAL_EQ | + DerivableTraits::EQ, ); let mut derives: Vec<_> = derives.into(); for derive in item.annotations().derives() { @@ -3856,8 +3856,8 @@ impl CodeGenerator for Enum { Entry::Occupied(ref entry) => { if variation.is_rust() { let variant_name = ctx.rust_mangle(variant.name()); - let mangled_name = if is_toplevel - || enum_ty.name().is_some() + let mangled_name = if is_toplevel || + enum_ty.name().is_some() { variant_name } else { @@ -3916,8 +3916,8 @@ impl CodeGenerator for Enum { // If it's an unnamed enum, or constification is enforced, // we also generate a constant so it can be properly // accessed. - if (variation.is_rust() && enum_ty.name().is_none()) - || variant.force_constification() + if (variation.is_rust() && enum_ty.name().is_none()) || + variant.force_constification() { let mangled_name = if is_toplevel { variant_name.clone() @@ -4360,17 +4360,16 @@ impl TryToRustTy for Type { inst.try_to_rust_ty(ctx, item) } TypeKind::ResolvedTypeRef(inner) => inner.try_to_rust_ty(ctx, &()), - TypeKind::TemplateAlias(..) - | TypeKind::Alias(..) - | TypeKind::BlockPointer(..) => { + TypeKind::TemplateAlias(..) | + TypeKind::Alias(..) | + TypeKind::BlockPointer(..) => { if self.is_block_pointer() && !ctx.options().generate_block { let void = c_void(ctx); return Ok(void.to_ptr(/* is_const = */ false)); } - if item.is_opaque(ctx, &()) - && item - .used_template_params(ctx) + if item.is_opaque(ctx, &()) && + item.used_template_params(ctx) .into_iter() .any(|param| param.is_template_param(ctx, &())) { @@ -4386,8 +4385,8 @@ impl TryToRustTy for Type { } TypeKind::Comp(ref info) => { let template_params = item.all_template_params(ctx); - if info.has_non_type_template_params() - || (item.is_opaque(ctx, &()) && !template_params.is_empty()) + if info.has_non_type_template_params() || + (item.is_opaque(ctx, &()) && !template_params.is_empty()) { return self.try_to_opaque(ctx, item); } @@ -4738,9 +4737,9 @@ impl CodeGenerator for Function { } } - let should_wrap = is_internal - && ctx.options().wrap_static_fns - && link_name_attr.is_none(); + let should_wrap = is_internal && + ctx.options().wrap_static_fns && + link_name_attr.is_none(); if should_wrap { let name = canonical_name.clone() + ctx.wrap_static_fns_suffix(); @@ -5284,8 +5283,8 @@ pub(crate) mod utils { std::fs::create_dir_all(dir)?; } - let is_cpp = args_are_cpp(&context.options().clang_args) - || context + let is_cpp = args_are_cpp(&context.options().clang_args) || + context .options() .input_headers .iter() @@ -5383,8 +5382,8 @@ pub(crate) mod utils { ctx: &BindgenContext, result: &mut Vec, ) { - if ctx.options().blocklisted_items.matches(BITFIELD_UNIT) - || ctx.options().blocklisted_types.matches(BITFIELD_UNIT) + if ctx.options().blocklisted_items.matches(BITFIELD_UNIT) || + ctx.options().blocklisted_types.matches(BITFIELD_UNIT) { return; }