diff options
author | Karel Peeters <karel.peeters.leuven@gmail.com> | 2021-07-23 17:43:44 +0200 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2021-07-31 13:47:39 +0200 |
commit | 9833b6745d74896620ea760f3bf81f344a105f30 (patch) | |
tree | 98981ecc2b96d7fdafd8f737f460f3fc51214b19 | |
parent | d1d2eb62d36c462416a606c680e6b4ba4716daab (diff) |
Implement must_use_type commandline flag and builder option.
-rw-r--r-- | src/codegen/mod.rs | 4 | ||||
-rw-r--r-- | src/ir/context.rs | 6 | ||||
-rw-r--r-- | src/lib.rs | 13 | ||||
-rw-r--r-- | src/options.rs | 13 | ||||
-rw-r--r-- | tests/expectations/tests/issue-710-must-use-type.rs | 18 | ||||
-rw-r--r-- | tests/headers/issue-710-must-use-type.h | 5 |
6 files changed, 59 insertions, 0 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index 0f3337ac..76c64e4a 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -2023,6 +2023,10 @@ impl CodeGenerator for CompInfo { attributes.push(attributes::derives(&derives)) } + if ctx.must_use_type_by_name(item) { + attributes.push(attributes::must_use()); + } + let mut tokens = if is_union && struct_layout.is_rust_union() { quote! { #( #attributes )* diff --git a/src/ir/context.rs b/src/ir/context.rs index 72ce06b1..bd21058c 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -2663,6 +2663,12 @@ If you encounter an error missing from this list, please file an issue or a PR!" let name = item.path_for_allowlisting(self)[1..].join("::"); self.options().no_hash_types.matches(&name) } + + /// Check if `--must-use-type` flag is enabled for this item. + pub fn must_use_type_by_name(&self, item: &Item) -> bool { + let name = item.path_for_allowlisting(self)[1..].join("::"); + self.options().must_use_types.matches(&name) + } } /// A builder struct for configuring item resolution options. @@ -317,6 +317,7 @@ impl Builder { (&self.options.no_debug_types, "--no-debug"), (&self.options.no_default_types, "--no-default"), (&self.options.no_hash_types, "--no-hash"), + (&self.options.must_use_types, "--must-use-type"), ]; for (set, flag) in regex_sets { @@ -1588,6 +1589,13 @@ impl Builder { self } + /// Add `#[must_use]` for the given type. Regular + /// expressions are supported. + pub fn must_use_type<T: Into<String>>(mut self, arg: T) -> Builder { + self.options.must_use_types.insert(arg.into()); + self + } + /// Set whether `arr[size]` should be treated as `*mut T` or `*mut [T; size]` (same for mut) pub fn array_pointers_in_arguments(mut self, doit: bool) -> Self { self.options.array_pointers_in_arguments = doit; @@ -1928,6 +1936,9 @@ struct BindgenOptions { /// The set of types that we should not derive `Hash` for. no_hash_types: RegexSet, + /// The set of types that we should be annotated with `#[must_use]`. + must_use_types: RegexSet, + /// Decide if C arrays should be regular pointers in rust or array pointers array_pointers_in_arguments: bool, @@ -1986,6 +1997,7 @@ impl BindgenOptions { &mut self.no_debug_types, &mut self.no_default_types, &mut self.no_hash_types, + &mut self.must_use_types, ]; let record_matches = self.record_matches; for regex_set in &mut regex_sets { @@ -2090,6 +2102,7 @@ impl Default for BindgenOptions { no_debug_types: Default::default(), no_default_types: Default::default(), no_hash_types: Default::default(), + must_use_types: Default::default(), array_pointers_in_arguments: false, wasm_import_module_name: None, dynamic_library_name: None, diff --git a/src/options.rs b/src/options.rs index eeeb5aae..7f27e221 100644 --- a/src/options.rs +++ b/src/options.rs @@ -486,6 +486,13 @@ where .takes_value(true) .multiple(true) .number_of_values(1), + Arg::with_name("must-use-type") + .long("must-use-type") + .help("Add #[must_use] annotation to types matching <regex>.") + .value_name("regex") + .takes_value(true) + .multiple(true) + .number_of_values(1), Arg::with_name("enable-function-attribute-detection") .long("enable-function-attribute-detection") .help( @@ -942,6 +949,12 @@ where builder = builder.no_hash(regex); } } + + if let Some(must_use_type) = matches.values_of("must-use-type") { + for regex in must_use_type { + builder = builder.must_use_type(regex); + } + } if let Some(dynamic_library_name) = matches.value_of("dynamic-loading") { builder = builder.dynamic_library_name(dynamic_library_name); diff --git a/tests/expectations/tests/issue-710-must-use-type.rs b/tests/expectations/tests/issue-710-must-use-type.rs new file mode 100644 index 00000000..20a713e4 --- /dev/null +++ b/tests/expectations/tests/issue-710-must-use-type.rs @@ -0,0 +1,18 @@ +#![allow( + dead_code, + non_snake_case, + non_camel_case_types, + non_upper_case_globals +)] + +#[repr(C)] +#[derive(Debug, Copy, Clone)] +#[must_use] +pub struct MyType { + _unused: [u8; 0], +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct OtherType { + _unused: [u8; 0], +} diff --git a/tests/headers/issue-710-must-use-type.h b/tests/headers/issue-710-must-use-type.h new file mode 100644 index 00000000..0c047e61 --- /dev/null +++ b/tests/headers/issue-710-must-use-type.h @@ -0,0 +1,5 @@ +// bindgen-flags: --must-use-type MyType + +struct MyType; + +struct OtherType; |