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)]