needless_borrow: do not contradict dangerous_implicit_autorefs (rust-lang/rust-clippy#14810)

Rust 1.88 introduces the `dangerous_implicit_autorefs` lint which warns
about using implicit autorefs on a place obtained from a raw pointer, as
this may create aliasing issues.

Prevent `clippy::needless_borrow` from triggering in this case, by
disabling the lint when taking a reference on a raw pointer dereference.
There might be a better way for doing this in the long run with a finer
way of distinguish the problematic cases, but this will prevent Clippy
from contradicting the compiler in the meantime.

Fixes rust-lang/rust-clippy#14743

changelog: [`needless_borrow`]: do not contradict the compiler's
`dangerous_implicit_autorefs` lint even though the refererences are not
mandatory

@rustbot label +beta-nominated

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_SUMMARY_START -->


- [Beta nomination for
1.88](https://github.com/rust-lang/rust-clippy/pull/14810#issuecomment-2883753957)
by [samueltardieu](https://github.com/samueltardieu)

Generated by triagebot, see
[help](https://forge.rust-lang.org/triagebot/note.html) for how to add
more
<!--
TRIAGEBOT_SUMMARY_DATA_START$${"entries_by_url":{"https://github.com/rust-lang/rust-clippy/pull/14810#issuecomment-2883753957":{"title":"Beta
nomination for
1.88","comment_url":"https://github.com/rust-lang/rust-clippy/pull/14810#issuecomment-2883753957","author":"samueltardieu"}}}$$TRIAGEBOT_SUMMARY_DATA_END
-->

<!-- TRIAGEBOT_SUMMARY_END -->
<!-- TRIAGEBOT_END -->
This commit is contained in:
Alejandra González 2025-05-23 17:37:41 +00:00 committed by Josh Stone
parent fd334c7d6b
commit 2ec328fec2
4 changed files with 49 additions and 22 deletions

View file

@ -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);

View file

@ -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<T>(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() };
}

View file

@ -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<T>(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() };
}

View file

@ -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