Repository: rust-lang/rust-clippy (Rust)

Issue:
used_underscore_items should not warn about uses of foreign functions
### Summary

Currently, this lint warns about uses of foreign functions (functions in an extern block), but since the names of these functions are defined by the C (or other) library that exports them, there is no way to deal with them on our code side other than to allow lint or to use the redundant link_name attribute.



### Lint Name

used_underscore_items

### Reproducer

I tried this code:

```rust
#![warn(clippy::used_underscore_items)]

extern "C" {
    pub fn _exit(code: i32) -> !;
}

fn _f() {
    unsafe { _exit(1) }
}
```

I saw this happen:

```
warning: used underscore-prefixed item
 --> src/lib.rs:8:14
  |
8 |     unsafe { _exit(1) }
  |              ^^^^^^^^
  |
note: item is defined here
 --> src/lib.rs:4:5
  |
4 |     pub fn _exit(code: i32) -> !;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#used_underscore_items
note: the lint level is defined here
 --> src/lib.rs:1:9
  |
1 | #![warn(clippy::used_underscore_items)]
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

I expected to see this happen: no warning

[playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=c1d5303d4791318543e40276ab39a744)

### Version

```text
rustc 1.86.0-nightly (bef3c3b01 2025-02-04)
binary: rustc
commit-hash: bef3c3b01f690de16738b1c9f36470fbfc6ac623
commit-date: 2025-02-04
host: aarch64-apple-darwin
release: 1.86.0-nightly
LLVM version: 19.1.7
```

### Additional Labels

_No response_

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_ASSIGN_START -->

<!-- TRIAGEBOT_ASSIGN_DATA_START$${"user":"WeiTheShinobi"}$$TRIAGEBOT_ASSIGN_DATA_END -->

<!-- TRIAGEBOT_ASSIGN_END -->
<!-- TRIAGEBOT_END -->


Discussion:
cc @WeiTheShinobi (who implemented this lint in https://github.com/rust-lang/rust-clippy/pull/13294)
@rustbot claim



Patch:
diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs
index 8dbc41085532..646145997bc3 100644
--- a/clippy_lints/src/misc.rs
+++ b/clippy_lints/src/misc.rs
@@ -7,7 +7,6 @@ use clippy_utils::{
 };
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
-use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
     BinOpKind, BindingMode, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind,
@@ -287,7 +286,8 @@ fn used_underscore_items<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
     if name.starts_with('_')
         && !name.starts_with("__")
         && !definition_span.from_expansion()
-        && def_id.krate == LOCAL_CRATE
+        && def_id.is_local()
+        && !cx.tcx.is_foreign_item(def_id)
     {
         span_lint_and_then(
             cx,


Test patch:
diff --git a/tests/ui/used_underscore_items.rs b/tests/ui/used_underscore_items.rs
index 223016a5c966..ed76f4e68dc9 100644
--- a/tests/ui/used_underscore_items.rs
+++ b/tests/ui/used_underscore_items.rs
@@ -61,3 +61,13 @@ fn external_item_call() {
 
     external_item::_exernal_foo();
 }
+
+// should not lint foreign functions.
+// issue #14156
+extern "C" {
+    pub fn _exit(code: i32) -> !;
+}
+
+fn _f() {
+    unsafe { _exit(1) }
+}