ir: Centralize must_use checks and simplify codegen.
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index fdc9b5e..4dd5203 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -2082,8 +2082,7 @@
attributes.push(attributes::derives(&derives))
}
- if item.annotations().must_use_type() || ctx.must_use_type_by_name(item)
- {
+ if item.must_use(ctx) {
attributes.push(attributes::must_use());
}
@@ -3054,8 +3053,7 @@
attrs.push(attributes::doc(comment));
}
- if item.annotations().must_use_type() || ctx.must_use_type_by_name(item)
- {
+ if item.must_use(ctx) {
attrs.push(attributes::must_use());
}
@@ -3967,26 +3965,12 @@
if ctx.options().rust_features().must_use_function {
let must_use = signature.must_use() || {
- let ret_ty = signature.return_type();
-
- let resolved_ret = ret_ty
+ let ret_ty = signature
+ .return_type()
.into_resolver()
.through_type_refs()
- .through_type_aliases()
.resolve(ctx);
-
- let must_use_resolved_ty =
- resolved_ret.annotations().must_use_type() ||
- ctx.must_use_type_by_name(resolved_ret);
-
- let ret = ctx.resolve_item(ret_ty);
- let must_use_ty = ret.annotations().must_use_type() ||
- ctx.must_use_type_by_name(ret);
-
- // If the return type already has #[must_use], the function does not
- // need the annotation. This preserves the codegen behavior before
- // type aliases with #[must_use] were supported.
- !must_use_resolved_ty && must_use_ty
+ ret_ty.must_use(ctx)
};
if must_use {
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 2f71deb..9cf43ec 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -1921,8 +1921,7 @@
let item = Item::new(
with_id,
None,
- self.resolve_item_fallible(wrapped_id)
- .map(|item| item.annotations().clone()),
+ None,
parent_id.unwrap_or_else(|| self.current_module.into()),
ItemKind::Type(ty),
Some(location),
diff --git a/src/ir/item.rs b/src/ir/item.rs
index aed575c..6ce4201 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -1096,6 +1096,11 @@
_ => return None,
})
}
+
+ /// Whether this is a #[must_use] type.
+ pub fn must_use(&self, ctx: &BindgenContext) -> bool {
+ self.annotations().must_use_type() || ctx.must_use_type_by_name(self)
+ }
}
impl<T> IsOpaque for T
diff --git a/tests/expectations/tests/func_return_must_use.rs b/tests/expectations/tests/func_return_must_use.rs
index 9f40aaa..6ea6c70 100644
--- a/tests/expectations/tests/func_return_must_use.rs
+++ b/tests/expectations/tests/func_return_must_use.rs
@@ -17,6 +17,7 @@
_unused: [u8; 0],
}
extern "C" {
+ #[must_use]
pub fn return_struct() -> MustUseStruct;
}
/// <div rustbindgen mustusetype></div>
@@ -47,6 +48,7 @@
);
}
extern "C" {
+ #[must_use]
pub fn return_annotated_struct() -> AnnotatedStruct;
}
#[repr(C)]