summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Peeters <karel.peeters.leuven@gmail.com>2021-07-23 17:43:44 +0200
committerEmilio Cobos Álvarez <emilio@crisal.io>2021-07-31 13:47:39 +0200
commit9833b6745d74896620ea760f3bf81f344a105f30 (patch)
tree98981ecc2b96d7fdafd8f737f460f3fc51214b19
parentd1d2eb62d36c462416a606c680e6b4ba4716daab (diff)
Implement must_use_type commandline flag and builder option.
-rw-r--r--src/codegen/mod.rs4
-rw-r--r--src/ir/context.rs6
-rw-r--r--src/lib.rs13
-rw-r--r--src/options.rs13
-rw-r--r--tests/expectations/tests/issue-710-must-use-type.rs18
-rw-r--r--tests/headers/issue-710-must-use-type.h5
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.
diff --git a/src/lib.rs b/src/lib.rs
index 1c51c8ae..67cfeb3d 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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;