From a613460e8ade73dc387c19b0a45588681de46fef Mon Sep 17 00:00:00 2001 From: xFrednet Date: Mon, 6 Jun 2022 11:51:36 +0200 Subject: [PATCH 1/4] Fix `#[expect]` for `needless_borrow`, `ref_binding_to_ref` --- clippy_lints/src/dereference.rs | 45 ++++++++++++++---------- tests/ui/needless_borrow.fixed | 8 +++++ tests/ui/needless_borrow.rs | 8 +++++ tests/ui/needless_borrow.stderr | 32 ++++++++--------- tests/ui/ref_binding_to_reference.rs | 10 ++++++ tests/ui/ref_binding_to_reference.stderr | 14 ++++---- 6 files changed, 75 insertions(+), 42 deletions(-) diff --git a/clippy_lints/src/dereference.rs b/clippy_lints/src/dereference.rs index 8288f7a8b9b..6d32cc8253f 100644 --- a/clippy_lints/src/dereference.rs +++ b/clippy_lints/src/dereference.rs @@ -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::sugg::has_enclosing_paren; use clippy_utils::ty::peel_mid_ty_refs; @@ -131,6 +131,7 @@ pub struct Dereferencing { struct StateData { /// Span of the top level expression span: Span, + hir_id: HirId, } enum State { @@ -165,6 +166,8 @@ struct RefPat { 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 { @@ -218,7 +221,10 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { 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 => { @@ -290,7 +296,10 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { required_precedence, 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], app, 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) { 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| { @@ -638,19 +650,14 @@ fn report<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, state: State, data: S } => { 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); + }); }, } } diff --git a/tests/ui/needless_borrow.fixed b/tests/ui/needless_borrow.fixed index efeb5cf5b2b..6b1576d6732 100644 --- a/tests/ui/needless_borrow.fixed +++ b/tests/ui/needless_borrow.fixed @@ -1,5 +1,7 @@ // run-rustfix +#![feature(lint_reasons)] + #[warn(clippy::all, clippy::needless_borrow)] #[allow(unused_variables, clippy::unnecessary_mut_passed)] fn main() { @@ -96,3 +98,9 @@ trait Trait {} impl<'a> Trait for &'a str {} fn h(_: &dyn Trait) {} + +fn check_expect_suppression() { + let a = 5; + #[expect(clippy::needless_borrow)] + let _ = x(&&a); +} diff --git a/tests/ui/needless_borrow.rs b/tests/ui/needless_borrow.rs index 3e416a0eb84..ebe76361db4 100644 --- a/tests/ui/needless_borrow.rs +++ b/tests/ui/needless_borrow.rs @@ -1,5 +1,7 @@ // run-rustfix +#![feature(lint_reasons)] + #[warn(clippy::all, clippy::needless_borrow)] #[allow(unused_variables, clippy::unnecessary_mut_passed)] fn main() { @@ -96,3 +98,9 @@ trait Trait {} impl<'a> Trait for &'a str {} fn h(_: &dyn Trait) {} + +fn check_expect_suppression() { + let a = 5; + #[expect(clippy::needless_borrow)] + let _ = x(&&a); +} diff --git a/tests/ui/needless_borrow.stderr b/tests/ui/needless_borrow.stderr index 05591ce4117..be59d8f546d 100644 --- a/tests/ui/needless_borrow.stderr +++ b/tests/ui/needless_borrow.stderr @@ -1,5 +1,5 @@ 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` @@ -7,91 +7,91 @@ LL | let _ = x(&&a); // warn = 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)` diff --git a/tests/ui/ref_binding_to_reference.rs b/tests/ui/ref_binding_to_reference.rs index fe742a4c2f4..570ef406e4a 100644 --- a/tests/ui/ref_binding_to_reference.rs +++ b/tests/ui/ref_binding_to_reference.rs @@ -1,5 +1,6 @@ // FIXME: run-rustfix waiting on multi-span suggestions +#![feature(lint_reasons)] #![warn(clippy::ref_binding_to_reference)] #![allow(clippy::needless_borrowed_reference)] @@ -73,3 +74,12 @@ fn f(&ref x: &&String) { 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, + }; +} diff --git a/tests/ui/ref_binding_to_reference.stderr b/tests/ui/ref_binding_to_reference.stderr index c5856e15fa9..eb36cd516a2 100644 --- a/tests/ui/ref_binding_to_reference.stderr +++ b/tests/ui/ref_binding_to_reference.stderr @@ -1,5 +1,5 @@ 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, | ^^^^^ @@ -11,7 +11,7 @@ LL | Some(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) => { | ^^^^^ @@ -25,7 +25,7 @@ LL ~ &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), | ^^^^^ @@ -36,7 +36,7 @@ LL | Some(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| { | ^^^^^ @@ -48,7 +48,7 @@ LL ~ let _: &&String = &x; | 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 { | ^^^^^ @@ -61,7 +61,7 @@ LL ~ x | 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) { | ^^^^^ @@ -73,7 +73,7 @@ LL ~ let _: &&String = &x; | 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) { | ^^^^^ From 7e1730e16c779f688392e0edcd553036b2afe1f1 Mon Sep 17 00:00:00 2001 From: xFrednet Date: Mon, 6 Jun 2022 12:36:57 +0200 Subject: [PATCH 2/4] Fix `#[expect]` for `same_name_method` --- clippy_lints/src/same_name_method.rs | 17 ++++++++++------- tests/ui/same_name_method.rs | 16 ++++++++++++++++ tests/ui/same_name_method.stderr | 20 ++++++++++---------- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/same_name_method.rs b/clippy_lints/src/same_name_method.rs index 9158cbcc04e..04d9ee7d912 100644 --- a/clippy_lints/src/same_name_method.rs +++ b/clippy_lints/src/same_name_method.rs @@ -1,7 +1,7 @@ -use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::diagnostics::span_lint_hir_and_then; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::{Impl, ItemKind, Node, Path, QPath, TraitRef, TyKind}; +use rustc_hir::{HirId, Impl, ItemKind, Node, Path, QPath, TraitRef, TyKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::AssocKind; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -42,7 +42,7 @@ declare_lint_pass!(SameNameMethod => [SAME_NAME_METHOD]); struct ExistingName { - impl_methods: BTreeMap, + impl_methods: BTreeMap, trait_methods: BTreeMap>, } @@ -97,10 +97,11 @@ fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { }; let mut check_trait_method = |method_name: Symbol, trait_method_span: Span| { - if let Some(impl_span) = existing_name.impl_methods.get(&method_name) { - span_lint_and_then( + if let Some((impl_span, hir_id)) = existing_name.impl_methods.get(&method_name) { + span_lint_hir_and_then( cx, SAME_NAME_METHOD, + *hir_id, *impl_span, "method's name is the same as an existing method in a trait", |diag| { @@ -136,10 +137,12 @@ fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { }) { let method_name = impl_item_ref.ident.name; let impl_span = impl_item_ref.span; + let hir_id = impl_item_ref.id.hir_id(); if let Some(trait_spans) = existing_name.trait_methods.get(&method_name) { - span_lint_and_then( + span_lint_hir_and_then( cx, SAME_NAME_METHOD, + hir_id, impl_span, "method's name is the same as an existing method in a trait", |diag| { @@ -152,7 +155,7 @@ fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { }, ); } - existing_name.impl_methods.insert(method_name, impl_span); + existing_name.impl_methods.insert(method_name, (impl_span, hir_id)); } }, } diff --git a/tests/ui/same_name_method.rs b/tests/ui/same_name_method.rs index 12e10ba6c49..9562b47f0c4 100644 --- a/tests/ui/same_name_method.rs +++ b/tests/ui/same_name_method.rs @@ -1,3 +1,4 @@ +#![feature(lint_reasons)] #![warn(clippy::same_name_method)] #![allow(dead_code, non_camel_case_types)] @@ -108,4 +109,19 @@ impl T3 for S { } } +mod check_expect_suppression { + use crate::T1; + + struct S; + + impl S { + #[expect(clippy::same_name_method)] + fn foo() {} + } + + impl T1 for S { + fn foo() {} + } +} + fn main() {} diff --git a/tests/ui/same_name_method.stderr b/tests/ui/same_name_method.stderr index cf06eb32e0c..f55ec9f3cc6 100644 --- a/tests/ui/same_name_method.stderr +++ b/tests/ui/same_name_method.stderr @@ -1,61 +1,61 @@ error: method's name is the same as an existing method in a trait - --> $DIR/same_name_method.rs:20:13 + --> $DIR/same_name_method.rs:21:13 | LL | fn foo() {} | ^^^^^^^^^^^ | = note: `-D clippy::same-name-method` implied by `-D warnings` note: existing `foo` defined here - --> $DIR/same_name_method.rs:24:13 + --> $DIR/same_name_method.rs:25:13 | LL | fn foo() {} | ^^^^^^^^^^^ error: method's name is the same as an existing method in a trait - --> $DIR/same_name_method.rs:34:13 + --> $DIR/same_name_method.rs:35:13 | LL | fn clone() {} | ^^^^^^^^^^^^^ | note: existing `clone` defined here - --> $DIR/same_name_method.rs:30:18 + --> $DIR/same_name_method.rs:31:18 | LL | #[derive(Clone)] | ^^^^^ = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) error: method's name is the same as an existing method in a trait - --> $DIR/same_name_method.rs:44:13 + --> $DIR/same_name_method.rs:45:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> $DIR/same_name_method.rs:48:13 + --> $DIR/same_name_method.rs:49:13 | LL | fn foo() {} | ^^^^^^^^^^^ error: method's name is the same as an existing method in a trait - --> $DIR/same_name_method.rs:58:13 + --> $DIR/same_name_method.rs:59:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> $DIR/same_name_method.rs:61:9 + --> $DIR/same_name_method.rs:62:9 | LL | impl T1 for S {} | ^^^^^^^^^^^^^^^^ error: method's name is the same as an existing method in a trait - --> $DIR/same_name_method.rs:70:13 + --> $DIR/same_name_method.rs:71:13 | LL | fn foo() {} | ^^^^^^^^^^^ | note: existing `foo` defined here - --> $DIR/same_name_method.rs:73:9 + --> $DIR/same_name_method.rs:74:9 | LL | impl T1 for S {} | ^^^^^^^^^^^^^^^^ From 8db734990be40e2acd59c2b20bf6e02343830fd6 Mon Sep 17 00:00:00 2001 From: xFrednet Date: Mon, 6 Jun 2022 14:03:11 +0200 Subject: [PATCH 3/4] Fix `#[expect]` for `async_yields_async` --- clippy_lints/src/async_yields_async.rs | 5 +++-- clippy_lints/src/same_name_method.rs | 1 + tests/ui/async_yields_async.fixed | 13 ++++++++++++- tests/ui/async_yields_async.rs | 13 ++++++++++++- tests/ui/needless_borrow.fixed | 1 + tests/ui/needless_borrow.rs | 1 + 6 files changed, 30 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/async_yields_async.rs b/clippy_lints/src/async_yields_async.rs index 0619490e73c..d32724d040c 100644 --- a/clippy_lints/src/async_yields_async.rs +++ b/clippy_lints/src/async_yields_async.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::source::snippet; use clippy_utils::ty::implements_trait; use rustc_errors::Applicability; @@ -63,9 +63,10 @@ fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { _ => None, }; if let Some(return_expr_span) = return_expr_span { - span_lint_and_then( + span_lint_hir_and_then( cx, ASYNC_YIELDS_ASYNC, + body.value.hir_id, return_expr_span, "an async construct yields a type which is itself awaitable", |db| { diff --git a/clippy_lints/src/same_name_method.rs b/clippy_lints/src/same_name_method.rs index 04d9ee7d912..73f8e083b29 100644 --- a/clippy_lints/src/same_name_method.rs +++ b/clippy_lints/src/same_name_method.rs @@ -47,6 +47,7 @@ struct ExistingName { } impl<'tcx> LateLintPass<'tcx> for SameNameMethod { + #[expect(clippy::too_many_lines)] fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { let mut map = FxHashMap::::default(); diff --git a/tests/ui/async_yields_async.fixed b/tests/ui/async_yields_async.fixed index e20b58269b9..3cf380d2b95 100644 --- a/tests/ui/async_yields_async.fixed +++ b/tests/ui/async_yields_async.fixed @@ -1,5 +1,5 @@ // run-rustfix - +#![feature(lint_reasons)] #![feature(async_closure)] #![warn(clippy::async_yields_async)] @@ -65,3 +65,14 @@ fn main() { let _n = async || custom_future_type_ctor(); let _o = async || f(); } + +#[rustfmt::skip] +#[allow(dead_code)] +fn check_expect_suppression() { + #[expect(clippy::async_yields_async)] + let _j = async || { + async { + 3 + } + }; +} diff --git a/tests/ui/async_yields_async.rs b/tests/ui/async_yields_async.rs index c1dfa398450..dd4131b60ab 100644 --- a/tests/ui/async_yields_async.rs +++ b/tests/ui/async_yields_async.rs @@ -1,5 +1,5 @@ // run-rustfix - +#![feature(lint_reasons)] #![feature(async_closure)] #![warn(clippy::async_yields_async)] @@ -65,3 +65,14 @@ fn main() { let _n = async || custom_future_type_ctor(); let _o = async || f(); } + +#[rustfmt::skip] +#[allow(dead_code)] +fn check_expect_suppression() { + #[expect(clippy::async_yields_async)] + let _j = async || { + async { + 3 + } + }; +} diff --git a/tests/ui/needless_borrow.fixed b/tests/ui/needless_borrow.fixed index 6b1576d6732..e7a483c0582 100644 --- a/tests/ui/needless_borrow.fixed +++ b/tests/ui/needless_borrow.fixed @@ -99,6 +99,7 @@ impl<'a> Trait for &'a str {} fn h(_: &dyn Trait) {} +#[allow(dead_code)] fn check_expect_suppression() { let a = 5; #[expect(clippy::needless_borrow)] diff --git a/tests/ui/needless_borrow.rs b/tests/ui/needless_borrow.rs index ebe76361db4..1d6bf46405a 100644 --- a/tests/ui/needless_borrow.rs +++ b/tests/ui/needless_borrow.rs @@ -99,6 +99,7 @@ impl<'a> Trait for &'a str {} fn h(_: &dyn Trait) {} +#[allow(dead_code)] fn check_expect_suppression() { let a = 5; #[expect(clippy::needless_borrow)] From 9d201d68b41eefab9bae6f61de1eccb881524ccc Mon Sep 17 00:00:00 2001 From: xFrednet Date: Thu, 9 Jun 2022 09:17:46 +0200 Subject: [PATCH 4/4] Fix `#[expect]` for `default_numeric_fallback` --- clippy_lints/src/default_numeric_fallback.rs | 15 +++--- tests/ui/default_numeric_fallback_i32.fixed | 6 +++ tests/ui/default_numeric_fallback_i32.rs | 6 +++ tests/ui/default_numeric_fallback_i32.stderr | 50 ++++++++++---------- 4 files changed, 45 insertions(+), 32 deletions(-) diff --git a/clippy_lints/src/default_numeric_fallback.rs b/clippy_lints/src/default_numeric_fallback.rs index 3d9f9ed41ce..fb418a3251f 100644 --- a/clippy_lints/src/default_numeric_fallback.rs +++ b/clippy_lints/src/default_numeric_fallback.rs @@ -1,4 +1,4 @@ -use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::diagnostics::span_lint_hir_and_then; use clippy_utils::numeric_literal; use clippy_utils::source::snippet_opt; use if_chain::if_chain; @@ -76,7 +76,7 @@ fn new(cx: &'a LateContext<'tcx>) -> Self { } /// Check whether a passed literal has potential to cause fallback or not. - fn check_lit(&self, lit: &Lit, lit_ty: Ty<'tcx>) { + fn check_lit(&self, lit: &Lit, lit_ty: Ty<'tcx>, emit_hir_id: HirId) { if_chain! { if !in_external_macro(self.cx.sess(), lit.span); if let Some(ty_bound) = self.ty_bounds.last(); @@ -101,14 +101,15 @@ fn check_lit(&self, lit: &Lit, lit_ty: Ty<'tcx>) { } }; let sugg = numeric_literal::format(&src, Some(suffix), is_float); - span_lint_and_sugg( + span_lint_hir_and_then( self.cx, DEFAULT_NUMERIC_FALLBACK, + emit_hir_id, lit.span, "default numeric fallback might occur", - "consider adding suffix", - sugg, - Applicability::MaybeIncorrect, + |diag| { + diag.span_suggestion(lit.span, "consider adding suffix", sugg, Applicability::MaybeIncorrect); + } ); } } @@ -179,7 +180,7 @@ fn visit_expr(&mut self, expr: &'tcx Expr<'_>) { ExprKind::Lit(lit) => { let ty = self.cx.typeck_results().expr_ty(expr); - self.check_lit(lit, ty); + self.check_lit(lit, ty, expr.hir_id); return; }, diff --git a/tests/ui/default_numeric_fallback_i32.fixed b/tests/ui/default_numeric_fallback_i32.fixed index fa85d278c8f..55451cf2f7d 100644 --- a/tests/ui/default_numeric_fallback_i32.fixed +++ b/tests/ui/default_numeric_fallback_i32.fixed @@ -1,6 +1,7 @@ // run-rustfix // aux-build:macro_rules.rs +#![feature(lint_reasons)] #![warn(clippy::default_numeric_fallback)] #![allow( unused, @@ -173,4 +174,9 @@ mod in_macro { } } +fn check_expect_suppression() { + #[expect(clippy::default_numeric_fallback)] + let x = 21; +} + fn main() {} diff --git a/tests/ui/default_numeric_fallback_i32.rs b/tests/ui/default_numeric_fallback_i32.rs index 71acccd702b..62d72f2feba 100644 --- a/tests/ui/default_numeric_fallback_i32.rs +++ b/tests/ui/default_numeric_fallback_i32.rs @@ -1,6 +1,7 @@ // run-rustfix // aux-build:macro_rules.rs +#![feature(lint_reasons)] #![warn(clippy::default_numeric_fallback)] #![allow( unused, @@ -173,4 +174,9 @@ fn external() { } } +fn check_expect_suppression() { + #[expect(clippy::default_numeric_fallback)] + let x = 21; +} + fn main() {} diff --git a/tests/ui/default_numeric_fallback_i32.stderr b/tests/ui/default_numeric_fallback_i32.stderr index 3cc84ff1132..f7c5e724c40 100644 --- a/tests/ui/default_numeric_fallback_i32.stderr +++ b/tests/ui/default_numeric_fallback_i32.stderr @@ -1,5 +1,5 @@ error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:20:17 + --> $DIR/default_numeric_fallback_i32.rs:21:17 | LL | let x = 22; | ^^ help: consider adding suffix: `22_i32` @@ -7,145 +7,145 @@ LL | let x = 22; = note: `-D clippy::default-numeric-fallback` implied by `-D warnings` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:21:18 + --> $DIR/default_numeric_fallback_i32.rs:22:18 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:21:21 + --> $DIR/default_numeric_fallback_i32.rs:22:21 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:21:24 + --> $DIR/default_numeric_fallback_i32.rs:22:24 | LL | let x = [1, 2, 3]; | ^ help: consider adding suffix: `3_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:22:28 + --> $DIR/default_numeric_fallback_i32.rs:23:28 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:22:31 + --> $DIR/default_numeric_fallback_i32.rs:23:31 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:22:44 + --> $DIR/default_numeric_fallback_i32.rs:23:44 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `3_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:22:47 + --> $DIR/default_numeric_fallback_i32.rs:23:47 | LL | let x = if true { (1, 2) } else { (3, 4) }; | ^ help: consider adding suffix: `4_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:23:23 + --> $DIR/default_numeric_fallback_i32.rs:24:23 | LL | let x = match 1 { | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:24:13 + --> $DIR/default_numeric_fallback_i32.rs:25:13 | LL | 1 => 1, | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:24:18 + --> $DIR/default_numeric_fallback_i32.rs:25:18 | LL | 1 => 1, | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:25:18 + --> $DIR/default_numeric_fallback_i32.rs:26:18 | LL | _ => 2, | ^ help: consider adding suffix: `2_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:42:21 + --> $DIR/default_numeric_fallback_i32.rs:43:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:50:21 + --> $DIR/default_numeric_fallback_i32.rs:51:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:56:21 + --> $DIR/default_numeric_fallback_i32.rs:57:21 | LL | let y = 1; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:68:9 + --> $DIR/default_numeric_fallback_i32.rs:69:9 | LL | 1 | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:74:27 + --> $DIR/default_numeric_fallback_i32.rs:75:27 | LL | let f = || -> _ { 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:78:29 + --> $DIR/default_numeric_fallback_i32.rs:79:29 | LL | let f = || -> i32 { 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:92:21 + --> $DIR/default_numeric_fallback_i32.rs:93:21 | LL | generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:95:32 + --> $DIR/default_numeric_fallback_i32.rs:96:32 | LL | let x: _ = generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:113:28 + --> $DIR/default_numeric_fallback_i32.rs:114:28 | LL | GenericStruct { x: 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:116:36 + --> $DIR/default_numeric_fallback_i32.rs:117:36 | LL | let _ = GenericStruct { x: 1 }; | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:134:24 + --> $DIR/default_numeric_fallback_i32.rs:135:24 | LL | GenericEnum::X(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:154:23 + --> $DIR/default_numeric_fallback_i32.rs:155:23 | LL | s.generic_arg(1); | ^ help: consider adding suffix: `1_i32` error: default numeric fallback might occur - --> $DIR/default_numeric_fallback_i32.rs:161:21 + --> $DIR/default_numeric_fallback_i32.rs:162:21 | LL | let x = 22; | ^^ help: consider adding suffix: `22_i32`