From ced8bc5b8f105745d199da526ab262d17995d503 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Sat, 9 Mar 2024 17:09:17 +0100 Subject: [PATCH] use `span_lint_hir` instead of `span_lint` in more lints --- clippy_lints/src/let_if_seq.rs | 5 +- clippy_lints/src/mut_mut.rs | 8 +-- clippy_lints/src/read_zero_byte_vec.rs | 60 ++++++++++++++-------- clippy_lints/src/redundant_closure_call.rs | 5 +- clippy_lints/src/returns.rs | 31 +++++++---- clippy_lints/src/unused_io_amount.rs | 16 +++--- clippy_lints/src/unused_peekable.rs | 10 ++-- tests/ui/let_if_seq.rs | 11 ++++ tests/ui/let_if_seq.stderr | 8 +-- tests/ui/mut_mut.rs | 5 ++ tests/ui/needless_return.fixed | 7 +++ tests/ui/needless_return.rs | 7 +++ tests/ui/read_zero_byte_vec.rs | 6 +++ tests/ui/unused_io_amount.rs | 5 ++ tests/ui/unused_peekable.rs | 6 +++ 15 files changed, 136 insertions(+), 54 deletions(-) diff --git a/clippy_lints/src/let_if_seq.rs b/clippy_lints/src/let_if_seq.rs index 270162ae7..a2f167688 100644 --- a/clippy_lints/src/let_if_seq.rs +++ b/clippy_lints/src/let_if_seq.rs @@ -1,4 +1,4 @@ -use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::path_to_local_id; use clippy_utils::source::snippet; use clippy_utils::visitors::is_local_used; @@ -122,9 +122,10 @@ impl<'tcx> LateLintPass<'tcx> for LetIfSeq { value=snippet(cx, value.span, ""), default=snippet(cx, default.span, ""), ); - span_lint_and_then( + span_lint_hir_and_then( cx, USELESS_LET_IF_SEQ, + local.hir_id, span, "`if _ { .. } else { .. }` is an expression", |diag| { diff --git a/clippy_lints/src/mut_mut.rs b/clippy_lints/src/mut_mut.rs index beb6f170e..bc7b2c6b7 100644 --- a/clippy_lints/src/mut_mut.rs +++ b/clippy_lints/src/mut_mut.rs @@ -1,4 +1,4 @@ -use clippy_utils::diagnostics::span_lint; +use clippy_utils::diagnostics::{span_lint, span_lint_hir}; use clippy_utils::higher; use rustc_hir as hir; use rustc_hir::intravisit; @@ -87,17 +87,19 @@ impl<'a, 'tcx> intravisit::Visitor<'tcx> for MutVisitor<'a, 'tcx> { intravisit::walk_expr(self, body); } else if let hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, e) = expr.kind { if let hir::ExprKind::AddrOf(hir::BorrowKind::Ref, hir::Mutability::Mut, _) = e.kind { - span_lint( + span_lint_hir( self.cx, MUT_MUT, + expr.hir_id, expr.span, "generally you want to avoid `&mut &mut _` if possible", ); } else if let ty::Ref(_, ty, hir::Mutability::Mut) = self.cx.typeck_results().expr_ty(e).kind() { if ty.peel_refs().is_sized(self.cx.tcx, self.cx.param_env) { - span_lint( + span_lint_hir( self.cx, MUT_MUT, + expr.hir_id, expr.span, "this expression mutably borrows a mutable reference. Consider reborrowing", ); diff --git a/clippy_lints/src/read_zero_byte_vec.rs b/clippy_lints/src/read_zero_byte_vec.rs index 650324d42..302c9f286 100644 --- a/clippy_lints/src/read_zero_byte_vec.rs +++ b/clippy_lints/src/read_zero_byte_vec.rs @@ -1,4 +1,4 @@ -use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg}; +use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then}; use clippy_utils::get_enclosing_block; use clippy_utils::higher::{get_vec_init_kind, VecInitKind}; use clippy_utils::source::snippet; @@ -77,36 +77,52 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec { if let Some(expr) = visitor.read_zero_expr { let applicability = Applicability::MaybeIncorrect; match vec_init_kind { - VecInitKind::WithConstCapacity(len) => { - span_lint_and_sugg( - cx, - READ_ZERO_BYTE_VEC, - expr.span, - "reading zero byte data to `Vec`", - "try", - format!("{}.resize({len}, 0); {}", ident.as_str(), snippet(cx, expr.span, "..")), - applicability, - ); - }, + VecInitKind::WithConstCapacity(len) => span_lint_hir_and_then( + cx, + READ_ZERO_BYTE_VEC, + expr.hir_id, + expr.span, + "reading zero byte data to `Vec`", + |diag| { + diag.span_suggestion( + expr.span, + "try", + format!("{}.resize({len}, 0); {}", ident.as_str(), snippet(cx, expr.span, "..")), + applicability, + ); + }, + ), VecInitKind::WithExprCapacity(hir_id) => { let e = cx.tcx.hir().expect_expr(hir_id); - span_lint_and_sugg( + span_lint_hir_and_then( cx, READ_ZERO_BYTE_VEC, + expr.hir_id, expr.span, "reading zero byte data to `Vec`", - "try", - format!( - "{}.resize({}, 0); {}", - ident.as_str(), - snippet(cx, e.span, ".."), - snippet(cx, expr.span, "..") - ), - applicability, + |diag| { + diag.span_suggestion( + expr.span, + "try", + format!( + "{}.resize({}, 0); {}", + ident.as_str(), + snippet(cx, e.span, ".."), + snippet(cx, expr.span, "..") + ), + applicability, + ); + }, ); }, _ => { - span_lint(cx, READ_ZERO_BYTE_VEC, expr.span, "reading zero byte data to `Vec`"); + span_lint_hir( + cx, + READ_ZERO_BYTE_VEC, + expr.hir_id, + expr.span, + "reading zero byte data to `Vec`", + ); }, } } diff --git a/clippy_lints/src/redundant_closure_call.rs b/clippy_lints/src/redundant_closure_call.rs index f61527cc0..d53b3e118 100644 --- a/clippy_lints/src/redundant_closure_call.rs +++ b/clippy_lints/src/redundant_closure_call.rs @@ -1,5 +1,5 @@ use crate::rustc_lint::LintContext; -use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; +use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir}; use clippy_utils::get_parent_expr; use clippy_utils::sugg::Sugg; use hir::Param; @@ -273,9 +273,10 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall { && ident == path.segments[0].ident && count_closure_usage(cx, block, path) == 1 { - span_lint( + span_lint_hir( cx, REDUNDANT_CLOSURE_CALL, + second.hir_id, second.span, "closure called just once immediately after it was declared", ); diff --git a/clippy_lints/src/returns.rs b/clippy_lints/src/returns.rs index 2af466d3f..0b72c8a07 100644 --- a/clippy_lints/src/returns.rs +++ b/clippy_lints/src/returns.rs @@ -1,4 +1,4 @@ -use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then}; +use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then}; use clippy_utils::source::{snippet_opt, snippet_with_context}; use clippy_utils::sugg::has_enclosing_paren; use clippy_utils::visitors::{for_each_expr_with_closures, Descend}; @@ -380,7 +380,7 @@ fn check_final_expr<'tcx>( return; } - emit_return_lint(cx, ret_span, semi_spans, &replacement); + emit_return_lint(cx, ret_span, semi_spans, &replacement, expr.hir_id); }, ExprKind::If(_, then, else_clause_opt) => { check_block_return(cx, &then.kind, peeled_drop_expr.span, semi_spans.clone()); @@ -415,18 +415,31 @@ fn expr_contains_conjunctive_ifs<'tcx>(expr: &'tcx Expr<'tcx>) -> bool { contains_if(expr, false) } -fn emit_return_lint(cx: &LateContext<'_>, ret_span: Span, semi_spans: Vec, replacement: &RetReplacement<'_>) { +fn emit_return_lint( + cx: &LateContext<'_>, + ret_span: Span, + semi_spans: Vec, + replacement: &RetReplacement<'_>, + at: HirId, +) { if ret_span.from_expansion() { return; } - span_lint_and_then(cx, NEEDLESS_RETURN, ret_span, "unneeded `return` statement", |diag| { - let suggestions = std::iter::once((ret_span, replacement.to_string())) - .chain(semi_spans.into_iter().map(|span| (span, String::new()))) - .collect(); + span_lint_hir_and_then( + cx, + NEEDLESS_RETURN, + at, + ret_span, + "unneeded `return` statement", + |diag| { + let suggestions = std::iter::once((ret_span, replacement.to_string())) + .chain(semi_spans.into_iter().map(|span| (span, String::new()))) + .collect(); - diag.multipart_suggestion_verbose(replacement.sugg_help(), suggestions, replacement.applicability()); - }); + diag.multipart_suggestion_verbose(replacement.sugg_help(), suggestions, replacement.applicability()); + }, + ); } fn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool { diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs index 6b3ea7700..4e508161e 100644 --- a/clippy_lints/src/unused_io_amount.rs +++ b/clippy_lints/src/unused_io_amount.rs @@ -1,7 +1,7 @@ -use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::macros::{is_panic, root_macro_call_first_node}; use clippy_utils::{is_res_lang_ctor, is_trait_method, match_trait_method, paths, peel_blocks}; -use hir::{ExprKind, PatKind}; +use hir::{ExprKind, HirId, PatKind}; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::declare_lint_pass; @@ -135,22 +135,22 @@ fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) { && is_ok_wild_or_dotdot_pattern(cx, pat) && let Some(op) = should_lint(cx, init) => { - emit_lint(cx, cond.span, op, &[pat.span]); + emit_lint(cx, cond.span, cond.hir_id, op, &[pat.span]); }, // we will capture only the case where the match is Ok( ) or Err( ) // prefer to match the minimum possible, and expand later if needed // to avoid false positives on something as used as this hir::ExprKind::Match(expr, [arm1, arm2], hir::MatchSource::Normal) if let Some(op) = should_lint(cx, expr) => { if non_consuming_ok_arm(cx, arm1) && non_consuming_err_arm(cx, arm2) { - emit_lint(cx, expr.span, op, &[arm1.pat.span]); + emit_lint(cx, expr.span, expr.hir_id, op, &[arm1.pat.span]); } if non_consuming_ok_arm(cx, arm2) && non_consuming_err_arm(cx, arm1) { - emit_lint(cx, expr.span, op, &[arm2.pat.span]); + emit_lint(cx, expr.span, expr.hir_id, op, &[arm2.pat.span]); } }, hir::ExprKind::Match(_, _, hir::MatchSource::Normal) => {}, _ if let Some(op) = should_lint(cx, expr) => { - emit_lint(cx, expr.span, op, &[]); + emit_lint(cx, expr.span, expr.hir_id, op, &[]); }, _ => {}, }; @@ -279,7 +279,7 @@ fn check_io_mode(cx: &LateContext<'_>, call: &hir::Expr<'_>) -> Option { } } -fn emit_lint(cx: &LateContext<'_>, span: Span, op: IoOp, wild_cards: &[Span]) { +fn emit_lint(cx: &LateContext<'_>, span: Span, at: HirId, op: IoOp, wild_cards: &[Span]) { let (msg, help) = match op { IoOp::AsyncRead(false) => ( "read amount is not handled", @@ -301,7 +301,7 @@ fn emit_lint(cx: &LateContext<'_>, span: Span, op: IoOp, wild_cards: &[Span]) { IoOp::SyncWrite(true) | IoOp::AsyncWrite(true) => ("written amount is not handled", None), }; - span_lint_and_then(cx, UNUSED_IO_AMOUNT, span, msg, |diag| { + span_lint_hir_and_then(cx, UNUSED_IO_AMOUNT, at, span, msg, |diag| { if let Some(help_str) = help { diag.help(help_str); } diff --git a/clippy_lints/src/unused_peekable.rs b/clippy_lints/src/unused_peekable.rs index ba72b3450..9fc2476d3 100644 --- a/clippy_lints/src/unused_peekable.rs +++ b/clippy_lints/src/unused_peekable.rs @@ -1,4 +1,4 @@ -use clippy_utils::diagnostics::span_lint_and_help; +use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::ty::{is_type_diagnostic_item, peel_mid_ty_refs_is_mutable}; use clippy_utils::{fn_def_id, is_trait_method, path_to_local_id, peel_ref_operators}; use rustc_ast::Mutability; @@ -79,13 +79,15 @@ impl<'tcx> LateLintPass<'tcx> for UnusedPeekable { } if !vis.found_peek_call { - span_lint_and_help( + span_lint_hir_and_then( cx, UNUSED_PEEKABLE, + local.hir_id, ident.span, "`peek` never called on `Peekable` iterator", - None, - "consider removing the call to `peekable`", + |diag| { + diag.help("consider removing the call to `peekable`"); + }, ); } } diff --git a/tests/ui/let_if_seq.rs b/tests/ui/let_if_seq.rs index 9869d9452..a29d35880 100644 --- a/tests/ui/let_if_seq.rs +++ b/tests/ui/let_if_seq.rs @@ -57,6 +57,17 @@ fn early_return() -> u8 { foo } +fn allow_works() -> i32 { + #[allow(clippy::useless_let_if_seq)] + let x; + if true { + x = 1; + } else { + x = 2; + } + x +} + fn main() { early_return(); issue975(); diff --git a/tests/ui/let_if_seq.stderr b/tests/ui/let_if_seq.stderr index 87ad20dc2..41930108f 100644 --- a/tests/ui/let_if_seq.stderr +++ b/tests/ui/let_if_seq.stderr @@ -1,5 +1,5 @@ error: `if _ { .. } else { .. }` is an expression - --> tests/ui/let_if_seq.rs:66:5 + --> tests/ui/let_if_seq.rs:77:5 | LL | / let mut foo = 0; LL | | @@ -14,7 +14,7 @@ LL | | } = help: to override `-D warnings` add `#[allow(clippy::useless_let_if_seq)]` error: `if _ { .. } else { .. }` is an expression - --> tests/ui/let_if_seq.rs:73:5 + --> tests/ui/let_if_seq.rs:84:5 | LL | / let mut bar = 0; LL | | @@ -28,7 +28,7 @@ LL | | } = note: you might not need `mut` at all error: `if _ { .. } else { .. }` is an expression - --> tests/ui/let_if_seq.rs:83:5 + --> tests/ui/let_if_seq.rs:94:5 | LL | / let quz; LL | | @@ -40,7 +40,7 @@ LL | | } | |_____^ help: it is more idiomatic to write: `let quz = if f() { 42 } else { 0 };` error: `if _ { .. } else { .. }` is an expression - --> tests/ui/let_if_seq.rs:113:5 + --> tests/ui/let_if_seq.rs:124:5 | LL | / let mut baz = 0; LL | | diff --git a/tests/ui/mut_mut.rs b/tests/ui/mut_mut.rs index b454da3d2..4c45bc980 100644 --- a/tests/ui/mut_mut.rs +++ b/tests/ui/mut_mut.rs @@ -81,3 +81,8 @@ mod issue9035 { fn bar(_: &mut impl Display) {} } + +fn allow_works() { + #[allow(clippy::mut_mut)] + let _ = &mut &mut 1; +} diff --git a/tests/ui/needless_return.fixed b/tests/ui/needless_return.fixed index f9eb39d49..2575f2449 100644 --- a/tests/ui/needless_return.fixed +++ b/tests/ui/needless_return.fixed @@ -316,4 +316,11 @@ fn test_match_as_stmt() { }; } +fn allow_works() -> i32 { + #[allow(clippy::needless_return, clippy::match_single_binding)] + match () { + () => return 42, + } +} + fn main() {} diff --git a/tests/ui/needless_return.rs b/tests/ui/needless_return.rs index 4dd2e22ea..04f21834d 100644 --- a/tests/ui/needless_return.rs +++ b/tests/ui/needless_return.rs @@ -326,4 +326,11 @@ fn test_match_as_stmt() { }; } +fn allow_works() -> i32 { + #[allow(clippy::needless_return, clippy::match_single_binding)] + match () { + () => return 42, + } +} + fn main() {} diff --git a/tests/ui/read_zero_byte_vec.rs b/tests/ui/read_zero_byte_vec.rs index fd5a88a37..68acf4334 100644 --- a/tests/ui/read_zero_byte_vec.rs +++ b/tests/ui/read_zero_byte_vec.rs @@ -112,4 +112,10 @@ async fn test_tokio(r: &mut R) { //~^ ERROR: reading zero byte data to `Vec` } +fn allow_works(mut f: F) { + let mut data = Vec::with_capacity(100); + #[allow(clippy::read_zero_byte_vec)] + f.read(&mut data).unwrap(); +} + fn main() {} diff --git a/tests/ui/unused_io_amount.rs b/tests/ui/unused_io_amount.rs index 7e5a10c91..f5b200d5f 100644 --- a/tests/ui/unused_io_amount.rs +++ b/tests/ui/unused_io_amount.rs @@ -271,5 +271,10 @@ pub fn wildcards(rdr: &mut dyn std::io::Read) { } } } +fn allow_works(mut f: F) { + let mut data = Vec::with_capacity(100); + #[allow(clippy::unused_io_amount)] + f.read(&mut data).unwrap(); +} fn main() {} diff --git a/tests/ui/unused_peekable.rs b/tests/ui/unused_peekable.rs index 131b51e01..5865bba43 100644 --- a/tests/ui/unused_peekable.rs +++ b/tests/ui/unused_peekable.rs @@ -174,3 +174,9 @@ fn valid() { let mut peekable = std::iter::empty::().peekable(); takes_dyn(&mut peekable); } + +fn allow_works() { + #[allow(clippy::unused_peekable)] + let iter = [1, 2, 3].iter().peekable(); + iter; +}