about summary refs log tree commit diff
diff options
context:
space:
mode:
authoryanglsh <yanglsh@shanghaitech.edu.cn>2025-07-19 14:34:08 +0800
committeryanglsh <yanglsh@shanghaitech.edu.cn>2025-07-20 00:00:04 +0800
commit75811dfb6686d19fd4252dfe578a4ae3c8ee5d59 (patch)
tree73786905714b5aac5a37cc9e72f88711b8e8fa95
parentae8ff77d00f04cee9512c5b7d0bce7d61976bfaa (diff)
downloadrust-75811dfb6686d19fd4252dfe578a4ae3c8ee5d59.tar.gz
rust-75811dfb6686d19fd4252dfe578a4ae3c8ee5d59.zip
fix: `missing_inline_in_public_items` FP on functions with `extern`
-rw-r--r--clippy_lints/src/missing_inline.rs15
-rw-r--r--tests/ui/missing_inline.rs17
2 files changed, 30 insertions, 2 deletions
diff --git a/clippy_lints/src/missing_inline.rs b/clippy_lints/src/missing_inline.rs
index 25c95d23436..ca54fc693e7 100644
--- a/clippy_lints/src/missing_inline.rs
+++ b/clippy_lints/src/missing_inline.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint;
 use rustc_attr_data_structures::{AttributeKind, find_attr};
-use rustc_hir as hir;
-use rustc_hir::Attribute;
+use rustc_hir::def_id::DefId;
+use rustc_hir::{self as hir, Attribute};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::ty::AssocItemContainer;
 use rustc_session::declare_lint_pass;
@@ -97,6 +97,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
         }
         match it.kind {
             hir::ItemKind::Fn { .. } => {
+                if fn_is_externally_exported(cx, it.owner_id.to_def_id()) {
+                    return;
+                }
+
                 let desc = "a function";
                 let attrs = cx.tcx.hir_attrs(it.hir_id());
                 check_missing_inline_attrs(cx, attrs, it.span, desc);
@@ -173,3 +177,10 @@ impl<'tcx> LateLintPass<'tcx> for MissingInline {
         check_missing_inline_attrs(cx, attrs, impl_item.span, desc);
     }
 }
+
+/// Checks if this function is externally exported, where #[inline] wouldn't have the desired effect
+/// and a rustc warning would be triggered, see #15301
+fn fn_is_externally_exported(cx: &LateContext<'_>, def_id: DefId) -> bool {
+    let attrs = cx.tcx.codegen_fn_attrs(def_id);
+    attrs.contains_extern_indicator()
+}
diff --git a/tests/ui/missing_inline.rs b/tests/ui/missing_inline.rs
index c1801005b77..223c7447975 100644
--- a/tests/ui/missing_inline.rs
+++ b/tests/ui/missing_inline.rs
@@ -80,3 +80,20 @@ impl PubFoo {
 // do not lint this since users cannot control the external code
 #[derive(Debug)]
 pub struct S;
+
+pub mod issue15301 {
+    #[unsafe(no_mangle)]
+    pub extern "C" fn call_from_c() {
+        println!("Just called a Rust function from C!");
+    }
+
+    #[unsafe(no_mangle)]
+    pub extern "Rust" fn call_from_rust() {
+        println!("Just called a Rust function from Rust!");
+    }
+
+    #[unsafe(no_mangle)]
+    pub fn call_from_rust_no_extern() {
+        println!("Just called a Rust function from Rust!");
+    }
+}