-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::sugg::has_enclosing_paren;
use clippy_utils::ty::peel_mid_ty_refs;
struct StateData {
/// Span of the top level expression
span: Span,
+ hir_id: HirId,
}
enum State {
app: Applicability,
/// All the replacements which need to be made.
replacements: Vec<(Span, String)>,
+ /// The [`HirId`] that the lint should be emitted at.
+ hir_id: HirId,
}
impl<'tcx> LateLintPass<'tcx> for Dereferencing {
is_final_ufcs: matches!(expr.kind, ExprKind::Call(..)),
target_mut,
},
- StateData { span: expr.span },
+ StateData {
+ span: expr.span,
+ hir_id: expr.hir_id,
+ },
));
},
RefOp::AddrOf => {
required_precedence,
msg,
},
- StateData { span: expr.span },
+ StateData {
+ span: expr.span,
+ hir_id: expr.hir_id,
+ },
));
}
},
spans: vec![pat.span],
app,
replacements: vec![(pat.span, snip.into())],
+ hir_id: pat.hir_id
}),
);
}
for pat in self.ref_locals.drain(..).filter_map(|(_, x)| x) {
let replacements = pat.replacements;
let app = pat.app;
- span_lint_and_then(
+ let lint = if pat.always_deref {
+ NEEDLESS_BORROW
+ } else {
+ REF_BINDING_TO_REFERENCE
+ };
+ span_lint_hir_and_then(
cx,
- if pat.always_deref {
- NEEDLESS_BORROW
- } else {
- REF_BINDING_TO_REFERENCE
- },
+ lint,
+ pat.hir_id,
pat.spans,
"this pattern creates a reference to a reference",
|diag| {
} => {
let mut app = Applicability::MachineApplicable;
let snip = snippet_with_context(cx, expr.span, data.span.ctxt(), "..", &mut app).0;
- span_lint_and_sugg(
- cx,
- NEEDLESS_BORROW,
- data.span,
- msg,
- "change this to",
- if required_precedence > expr.precedence().order() && !has_enclosing_paren(&snip) {
+ span_lint_hir_and_then(cx, NEEDLESS_BORROW, data.hir_id, data.span, msg, |diag| {
+ let sugg = if required_precedence > expr.precedence().order() && !has_enclosing_paren(&snip) {
format!("({})", snip)
} else {
snip.into()
- },
- app,
- );
+ };
+ diag.span_suggestion(data.span, "change this to", sugg, app);
+ });
},
}
}
// run-rustfix
+#![feature(lint_reasons)]
+
#[warn(clippy::all, clippy::needless_borrow)]
#[allow(unused_variables, clippy::unnecessary_mut_passed)]
fn main() {
impl<'a> Trait for &'a str {}
fn h(_: &dyn Trait) {}
+
+fn check_expect_suppression() {
+ let a = 5;
+ #[expect(clippy::needless_borrow)]
+ let _ = x(&&a);
+}
// run-rustfix
+#![feature(lint_reasons)]
+
#[warn(clippy::all, clippy::needless_borrow)]
#[allow(unused_variables, clippy::unnecessary_mut_passed)]
fn main() {
impl<'a> Trait for &'a str {}
fn h(_: &dyn Trait) {}
+
+fn check_expect_suppression() {
+ let a = 5;
+ #[expect(clippy::needless_borrow)]
+ let _ = x(&&a);
+}
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
| ^^^ help: change this to: `&a`
= note: `-D clippy::needless-borrow` implied by `-D warnings`
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
| ^^^^^^^^^^^ help: change this to: `&mut b`
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
| ^^^ help: change this to: `&a`
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,
| ^^^ help: change this to: `&a`
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;
| ^^^^^^ help: change this to: `ref_a`
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);
| ^^^^ help: change this to: `&a`
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);
| ^^^^^^^^ help: change this to: `&a`
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);
| ^^^^^^^^ help: change this to: `&mut b`
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);
| ^^^^^^^ help: change this to: `ref_a`
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);
| ^^ help: change this to: `b`
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);
| ^^^^^^ help: change this to: `x`
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);
| ^^^^^^^^^^^ help: change this to: `x`
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;
| ^^^^^^ help: change this to: `x`
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;
| ^^^^^^^^^^^ help: change this to: `x`
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;
| ^^^^ help: change this to: `x`
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 };
| ^^^^^ help: change this to: `(*x)`
// FIXME: run-rustfix waiting on multi-span suggestions
+#![feature(lint_reasons)]
#![warn(clippy::ref_binding_to_reference)]
#![allow(clippy::needless_borrowed_reference)]
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,
+ };
+}
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,
| ^^^^^
| ~ ~~
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) => {
| ^^^^^
|
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),
| ^^^^^
| ~ ~~
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| {
| ^^^^^
|
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 {
| ^^^^^
|
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) {
| ^^^^^
|
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) {
| ^^^^^