diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs
index 5edb5c235703..a2cedba98327 100644
--- a/clippy_lints/src/dereference.rs
+++ b/clippy_lints/src/dereference.rs
@@ -997,6 +997,15 @@ fn report<'tcx>(
);
},
State::DerefedBorrow(state) => {
+ // Do not suggest removing a non-mandatory `&` in `&*rawptr` in an `unsafe` context,
+ // as this may make rustc trigger its `dangerous_implicit_autorefs` lint.
+ if let ExprKind::AddrOf(BorrowKind::Ref, _, subexpr) = data.first_expr.kind
+ && let ExprKind::Unary(UnOp::Deref, subsubexpr) = subexpr.kind
+ && cx.typeck_results().expr_ty_adjusted(subsubexpr).is_raw_ptr()
+ {
+ return;
+ }
+
let mut app = Applicability::MachineApplicable;
let (snip, snip_is_macro) =
snippet_with_context(cx, expr.span, data.first_expr.span.ctxt(), "..", &mut app);
diff --git a/tests/ui/needless_borrow.fixed b/tests/ui/needless_borrow.fixed
index d7d344452c5d..54cad2e393fd 100644
--- a/tests/ui/needless_borrow.fixed
+++ b/tests/ui/needless_borrow.fixed
@@ -107,9 +107,6 @@ fn main() {
let x = (1, 2);
let _ = x.0;
//~^ needless_borrow
- let x = &x as *const (i32, i32);
- let _ = unsafe { (*x).0 };
- //~^ needless_borrow
// Issue #8367
trait Foo {
@@ -289,3 +286,15 @@ fn issue_12268() {
// compiler
}
+
+fn issue_14743(slice: &[T]) {
+ let _ = slice.len();
+ //~^ needless_borrow
+
+ let slice = slice as *const [T];
+ let _ = unsafe { (&*slice).len() };
+
+ // Check that rustc would actually warn if Clippy had suggested removing the reference
+ #[expect(dangerous_implicit_autorefs)]
+ let _ = unsafe { (*slice).len() };
+}
diff --git a/tests/ui/needless_borrow.rs b/tests/ui/needless_borrow.rs
index 1f05b90b4728..b698c6bfc969 100644
--- a/tests/ui/needless_borrow.rs
+++ b/tests/ui/needless_borrow.rs
@@ -107,9 +107,6 @@ fn main() {
let x = (1, 2);
let _ = (&x).0;
//~^ needless_borrow
- let x = &x as *const (i32, i32);
- let _ = unsafe { (&*x).0 };
- //~^ needless_borrow
// Issue #8367
trait Foo {
@@ -289,3 +286,15 @@ fn issue_12268() {
// compiler
}
+
+fn issue_14743(slice: &[T]) {
+ let _ = (&slice).len();
+ //~^ needless_borrow
+
+ let slice = slice as *const [T];
+ let _ = unsafe { (&*slice).len() };
+
+ // Check that rustc would actually warn if Clippy had suggested removing the reference
+ #[expect(dangerous_implicit_autorefs)]
+ let _ = unsafe { (*slice).len() };
+}
diff --git a/tests/ui/needless_borrow.stderr b/tests/ui/needless_borrow.stderr
index b036b1e47d18..172d36bd73a0 100644
--- a/tests/ui/needless_borrow.stderr
+++ b/tests/ui/needless_borrow.stderr
@@ -103,71 +103,71 @@ error: this expression borrows a value the compiler would automatically borrow
LL | let _ = (&x).0;
| ^^^^ help: change this to: `x`
-error: this expression borrows a value the compiler would automatically borrow
- --> tests/ui/needless_borrow.rs:111:22
- |
-LL | let _ = unsafe { (&*x).0 };
- | ^^^^^ help: change this to: `(*x)`
-
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> tests/ui/needless_borrow.rs:122:5
+ --> tests/ui/needless_borrow.rs:119:5
|
LL | (&&()).foo();
| ^^^^^^ help: change this to: `(&())`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> tests/ui/needless_borrow.rs:132:5
+ --> tests/ui/needless_borrow.rs:129:5
|
LL | (&&5).foo();
| ^^^^^ help: change this to: `(&5)`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> tests/ui/needless_borrow.rs:159:23
+ --> tests/ui/needless_borrow.rs:156:23
|
LL | let x: (&str,) = (&"",);
| ^^^ help: change this to: `""`
error: this expression borrows a value the compiler would automatically borrow
- --> tests/ui/needless_borrow.rs:202:13
+ --> tests/ui/needless_borrow.rs:199:13
|
LL | (&self.f)()
| ^^^^^^^^^ help: change this to: `(self.f)`
error: this expression borrows a value the compiler would automatically borrow
- --> tests/ui/needless_borrow.rs:212:13
+ --> tests/ui/needless_borrow.rs:209:13
|
LL | (&mut self.f)()
| ^^^^^^^^^^^^^ help: change this to: `(self.f)`
error: this expression borrows a value the compiler would automatically borrow
- --> tests/ui/needless_borrow.rs:250:22
+ --> tests/ui/needless_borrow.rs:247:22
|
LL | let _ = &mut (&mut { x.u }).x;
| ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
error: this expression borrows a value the compiler would automatically borrow
- --> tests/ui/needless_borrow.rs:258:22
+ --> tests/ui/needless_borrow.rs:255:22
|
LL | let _ = &mut (&mut { x.u }).x;
| ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
error: this expression borrows a value the compiler would automatically borrow
- --> tests/ui/needless_borrow.rs:263:22
+ --> tests/ui/needless_borrow.rs:260:22
|
LL | let _ = &mut (&mut x.u).x;
| ^^^^^^^^^^ help: change this to: `x.u`
error: this expression borrows a value the compiler would automatically borrow
- --> tests/ui/needless_borrow.rs:265:22
+ --> tests/ui/needless_borrow.rs:262:22
|
LL | let _ = &mut (&mut { x.u }).x;
| ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
error: this expression creates a reference which is immediately dereferenced by the compiler
- --> tests/ui/needless_borrow.rs:287:23
+ --> tests/ui/needless_borrow.rs:284:23
|
LL | option.unwrap_or((&x.0,));
| ^^^^ help: change this to: `x.0`
+error: this expression creates a reference which is immediately dereferenced by the compiler
+ --> tests/ui/needless_borrow.rs:291:13
+ |
+LL | let _ = (&slice).len();
+ | ^^^^^^^^ help: change this to: `slice`
+
error: aborting due to 28 previous errors