Fix #[expect] for needless_borrow, ref_binding_to_ref

This commit is contained in:
xFrednet 2022-06-06 11:51:36 +02:00
parent 3e771624e1
commit a613460e8a
No known key found for this signature in database
GPG Key ID: F5C59D0E669E5302
6 changed files with 75 additions and 42 deletions

View File

@ -1,4 +1,4 @@
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then}; use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
use clippy_utils::source::{snippet_with_applicability, snippet_with_context}; use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
use clippy_utils::sugg::has_enclosing_paren; use clippy_utils::sugg::has_enclosing_paren;
use clippy_utils::ty::peel_mid_ty_refs; use clippy_utils::ty::peel_mid_ty_refs;
@ -131,6 +131,7 @@ pub struct Dereferencing {
struct StateData { struct StateData {
/// Span of the top level expression /// Span of the top level expression
span: Span, span: Span,
hir_id: HirId,
} }
enum State { enum State {
@ -165,6 +166,8 @@ struct RefPat {
app: Applicability, app: Applicability,
/// All the replacements which need to be made. /// All the replacements which need to be made.
replacements: Vec<(Span, String)>, replacements: Vec<(Span, String)>,
/// The [`HirId`] that the lint should be emitted at.
hir_id: HirId,
} }
impl<'tcx> LateLintPass<'tcx> for Dereferencing { impl<'tcx> LateLintPass<'tcx> for Dereferencing {
@ -218,7 +221,10 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
is_final_ufcs: matches!(expr.kind, ExprKind::Call(..)), is_final_ufcs: matches!(expr.kind, ExprKind::Call(..)),
target_mut, target_mut,
}, },
StateData { span: expr.span }, StateData {
span: expr.span,
hir_id: expr.hir_id,
},
)); ));
}, },
RefOp::AddrOf => { RefOp::AddrOf => {
@ -290,7 +296,10 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
required_precedence, required_precedence,
msg, msg,
}, },
StateData { span: expr.span }, StateData {
span: expr.span,
hir_id: expr.hir_id,
},
)); ));
} }
}, },
@ -383,6 +392,7 @@ fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
spans: vec![pat.span], spans: vec![pat.span],
app, app,
replacements: vec![(pat.span, snip.into())], replacements: vec![(pat.span, snip.into())],
hir_id: pat.hir_id
}), }),
); );
} }
@ -395,13 +405,15 @@ fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
for pat in self.ref_locals.drain(..).filter_map(|(_, x)| x) { for pat in self.ref_locals.drain(..).filter_map(|(_, x)| x) {
let replacements = pat.replacements; let replacements = pat.replacements;
let app = pat.app; let app = pat.app;
span_lint_and_then( let lint = if pat.always_deref {
cx,
if pat.always_deref {
NEEDLESS_BORROW NEEDLESS_BORROW
} else { } else {
REF_BINDING_TO_REFERENCE REF_BINDING_TO_REFERENCE
}, };
span_lint_hir_and_then(
cx,
lint,
pat.hir_id,
pat.spans, pat.spans,
"this pattern creates a reference to a reference", "this pattern creates a reference to a reference",
|diag| { |diag| {
@ -638,19 +650,14 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, state: State, data: S
} => { } => {
let mut app = Applicability::MachineApplicable; let mut app = Applicability::MachineApplicable;
let snip = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app).0; let snip = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app).0;
span_lint_and_sugg( span_lint_hir_and_then(cx, NEEDLESS_BORROW, data.hir_id, data.span, msg, |diag| {
cx, let sugg = if required_precedence > expr.precedence().order() && !has_enclosing_paren(&snip) {
NEEDLESS_BORROW,
data.span,
msg,
"change this to",
if required_precedence > expr.precedence().order() && !has_enclosing_paren(&snip) {
format!("({})", snip) format!("({})", snip)
} else { } else {
snip.into() snip.into()
}, };
app, diag.span_suggestion(data.span, "change this to", sugg, app);
); });
}, },
} }
} }

View File

@ -1,5 +1,7 @@
// run-rustfix // run-rustfix
#![feature(lint_reasons)]
#[warn(clippy::all, clippy::needless_borrow)] #[warn(clippy::all, clippy::needless_borrow)]
#[allow(unused_variables, clippy::unnecessary_mut_passed)] #[allow(unused_variables, clippy::unnecessary_mut_passed)]
fn main() { fn main() {
@ -96,3 +98,9 @@ trait Trait {}
impl<'a> Trait for &'a str {} impl<'a> Trait for &'a str {}
fn h(_: &dyn Trait) {} fn h(_: &dyn Trait) {}
fn check_expect_suppression() {
let a = 5;
#[expect(clippy::needless_borrow)]
let _ = x(&&a);
}

View File

@ -1,5 +1,7 @@
// run-rustfix // run-rustfix
#![feature(lint_reasons)]
#[warn(clippy::all, clippy::needless_borrow)] #[warn(clippy::all, clippy::needless_borrow)]
#[allow(unused_variables, clippy::unnecessary_mut_passed)] #[allow(unused_variables, clippy::unnecessary_mut_passed)]
fn main() { fn main() {
@ -96,3 +98,9 @@ trait Trait {}
impl<'a> Trait for &'a str {} impl<'a> Trait for &'a str {}
fn h(_: &dyn Trait) {} fn h(_: &dyn Trait) {}
fn check_expect_suppression() {
let a = 5;
#[expect(clippy::needless_borrow)]
let _ = x(&&a);
}

View File

@ -1,5 +1,5 @@
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:9:15 --> $DIR/needless_borrow.rs:11:15
| |
LL | let _ = x(&&a); // warn LL | let _ = x(&&a); // warn
| ^^^ help: change this to: `&a` | ^^^ help: change this to: `&a`
@ -7,91 +7,91 @@ LL | let _ = x(&&a); // warn
= note: `-D clippy::needless-borrow` implied by `-D warnings` = note: `-D clippy::needless-borrow` implied by `-D warnings`
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:13:13 --> $DIR/needless_borrow.rs:15:13
| |
LL | mut_ref(&mut &mut b); // warn LL | mut_ref(&mut &mut b); // warn
| ^^^^^^^^^^^ help: change this to: `&mut b` | ^^^^^^^^^^^ help: change this to: `&mut b`
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:25:13 --> $DIR/needless_borrow.rs:27:13
| |
LL | &&a LL | &&a
| ^^^ help: change this to: `&a` | ^^^ help: change this to: `&a`
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:27:15 --> $DIR/needless_borrow.rs:29:15
| |
LL | 46 => &&a, LL | 46 => &&a,
| ^^^ help: change this to: `&a` | ^^^ help: change this to: `&a`
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:33:27 --> $DIR/needless_borrow.rs:35:27
| |
LL | break &ref_a; LL | break &ref_a;
| ^^^^^^ help: change this to: `ref_a` | ^^^^^^ help: change this to: `ref_a`
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:40:15 --> $DIR/needless_borrow.rs:42:15
| |
LL | let _ = x(&&&a); LL | let _ = x(&&&a);
| ^^^^ help: change this to: `&a` | ^^^^ help: change this to: `&a`
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:41:15 --> $DIR/needless_borrow.rs:43:15
| |
LL | let _ = x(&mut &&a); LL | let _ = x(&mut &&a);
| ^^^^^^^^ help: change this to: `&a` | ^^^^^^^^ help: change this to: `&a`
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:42:15 --> $DIR/needless_borrow.rs:44:15
| |
LL | let _ = x(&&&mut b); LL | let _ = x(&&&mut b);
| ^^^^^^^^ help: change this to: `&mut b` | ^^^^^^^^ help: change this to: `&mut b`
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:43:15 --> $DIR/needless_borrow.rs:45:15
| |
LL | let _ = x(&&ref_a); LL | let _ = x(&&ref_a);
| ^^^^^^^ help: change this to: `ref_a` | ^^^^^^^ help: change this to: `ref_a`
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:46:11 --> $DIR/needless_borrow.rs:48:11
| |
LL | x(&b); LL | x(&b);
| ^^ help: change this to: `b` | ^^ help: change this to: `b`
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:53:13 --> $DIR/needless_borrow.rs:55:13
| |
LL | mut_ref(&mut x); LL | mut_ref(&mut x);
| ^^^^^^ help: change this to: `x` | ^^^^^^ help: change this to: `x`
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:54:13 --> $DIR/needless_borrow.rs:56:13
| |
LL | mut_ref(&mut &mut x); LL | mut_ref(&mut &mut x);
| ^^^^^^^^^^^ help: change this to: `x` | ^^^^^^^^^^^ help: change this to: `x`
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:55:23 --> $DIR/needless_borrow.rs:57:23
| |
LL | let y: &mut i32 = &mut x; LL | let y: &mut i32 = &mut x;
| ^^^^^^ help: change this to: `x` | ^^^^^^ help: change this to: `x`
error: this expression creates a reference which is immediately dereferenced by the compiler error: this expression creates a reference which is immediately dereferenced by the compiler
--> $DIR/needless_borrow.rs:56:23 --> $DIR/needless_borrow.rs:58:23
| |
LL | let y: &mut i32 = &mut &mut x; LL | let y: &mut i32 = &mut &mut x;
| ^^^^^^^^^^^ help: change this to: `x` | ^^^^^^^^^^^ help: change this to: `x`
error: this expression borrows a value the compiler would automatically borrow error: this expression borrows a value the compiler would automatically borrow
--> $DIR/needless_borrow.rs:72:13 --> $DIR/needless_borrow.rs:74:13
| |
LL | let _ = (&x).0; LL | let _ = (&x).0;
| ^^^^ help: change this to: `x` | ^^^^ help: change this to: `x`
error: this expression borrows a value the compiler would automatically borrow error: this expression borrows a value the compiler would automatically borrow
--> $DIR/needless_borrow.rs:74:22 --> $DIR/needless_borrow.rs:76:22
| |
LL | let _ = unsafe { (&*x).0 }; LL | let _ = unsafe { (&*x).0 };
| ^^^^^ help: change this to: `(*x)` | ^^^^^ help: change this to: `(*x)`

View File

@ -1,5 +1,6 @@
// FIXME: run-rustfix waiting on multi-span suggestions // FIXME: run-rustfix waiting on multi-span suggestions
#![feature(lint_reasons)]
#![warn(clippy::ref_binding_to_reference)] #![warn(clippy::ref_binding_to_reference)]
#![allow(clippy::needless_borrowed_reference)] #![allow(clippy::needless_borrowed_reference)]
@ -73,3 +74,12 @@ fn f(&ref x: &&String) {
let _: &&String = x; let _: &&String = x;
} }
} }
fn check_expect_suppression() {
let x = String::new();
#[expect(clippy::ref_binding_to_reference)]
let _: &&String = match Some(&x) {
Some(ref x) => x,
None => return,
};
}

View File

@ -1,5 +1,5 @@
error: this pattern creates a reference to a reference error: this pattern creates a reference to a reference
--> $DIR/ref_binding_to_reference.rs:30:14 --> $DIR/ref_binding_to_reference.rs:31:14
| |
LL | Some(ref x) => x, LL | Some(ref x) => x,
| ^^^^^ | ^^^^^
@ -11,7 +11,7 @@ LL | Some(x) => &x,
| ~ ~~ | ~ ~~
error: this pattern creates a reference to a reference error: this pattern creates a reference to a reference
--> $DIR/ref_binding_to_reference.rs:36:14 --> $DIR/ref_binding_to_reference.rs:37:14
| |
LL | Some(ref x) => { LL | Some(ref x) => {
| ^^^^^ | ^^^^^
@ -25,7 +25,7 @@ LL ~ &x
| |
error: this pattern creates a reference to a reference error: this pattern creates a reference to a reference
--> $DIR/ref_binding_to_reference.rs:46:14 --> $DIR/ref_binding_to_reference.rs:47:14
| |
LL | Some(ref x) => m2!(x), LL | Some(ref x) => m2!(x),
| ^^^^^ | ^^^^^
@ -36,7 +36,7 @@ LL | Some(x) => m2!(&x),
| ~ ~~ | ~ ~~
error: this pattern creates a reference to a reference error: this pattern creates a reference to a reference
--> $DIR/ref_binding_to_reference.rs:51:15 --> $DIR/ref_binding_to_reference.rs:52:15
| |
LL | let _ = |&ref x: &&String| { LL | let _ = |&ref x: &&String| {
| ^^^^^ | ^^^^^
@ -48,7 +48,7 @@ LL ~ let _: &&String = &x;
| |
error: this pattern creates a reference to a reference error: this pattern creates a reference to a reference
--> $DIR/ref_binding_to_reference.rs:57:12 --> $DIR/ref_binding_to_reference.rs:58:12
| |
LL | fn f2<'a>(&ref x: &&'a String) -> &'a String { LL | fn f2<'a>(&ref x: &&'a String) -> &'a String {
| ^^^^^ | ^^^^^
@ -61,7 +61,7 @@ LL ~ x
| |
error: this pattern creates a reference to a reference error: this pattern creates a reference to a reference
--> $DIR/ref_binding_to_reference.rs:64:11 --> $DIR/ref_binding_to_reference.rs:65:11
| |
LL | fn f(&ref x: &&String) { LL | fn f(&ref x: &&String) {
| ^^^^^ | ^^^^^
@ -73,7 +73,7 @@ LL ~ let _: &&String = &x;
| |
error: this pattern creates a reference to a reference error: this pattern creates a reference to a reference
--> $DIR/ref_binding_to_reference.rs:72:11 --> $DIR/ref_binding_to_reference.rs:73:11
| |
LL | fn f(&ref x: &&String) { LL | fn f(&ref x: &&String) {
| ^^^^^ | ^^^^^