From 12e4ff591abe236df6d4757e595073174a47053f Mon Sep 17 00:00:00 2001 From: J-ZhengLi Date: Thu, 16 May 2024 17:18:34 +0800 Subject: [PATCH] limit [`unconstrained_numeric_literal`] to simple local binding with lit Signed-off-by: J-ZhengLi --- .../unconstrained_numeric_literal.rs | 87 ++++------ .../unconstrained_numeric_literal.fixed | 33 +--- .../unconstrained_numeric_literal.rs | 31 ---- .../unconstrained_numeric_literal.stderr | 151 ++---------------- 4 files changed, 37 insertions(+), 265 deletions(-) diff --git a/clippy_lints/src/guidelines/unconstrained_numeric_literal.rs b/clippy_lints/src/guidelines/unconstrained_numeric_literal.rs index e5f641aee7c5..0a942bbb1b09 100644 --- a/clippy_lints/src/guidelines/unconstrained_numeric_literal.rs +++ b/clippy_lints/src/guidelines/unconstrained_numeric_literal.rs @@ -1,23 +1,21 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::is_lint_allowed; use clippy_utils::source::snippet_opt; -use rustc_errors::{Applicability, MultiSpan}; -use rustc_hir::intravisit::{walk_expr, Visitor}; +use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind, Local, TyKind}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_span::Span; use super::UNCONSTRAINED_NUMERIC_LITERAL; pub(super) fn check_local<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'tcx>) { if !is_lint_allowed(cx, UNCONSTRAINED_NUMERIC_LITERAL, local.hir_id) && let Some(init) = local.init + && let ExprKind::Lit(lit) = init.kind + && !in_external_macro(cx.sess(), lit.span) + && (lit.node.is_numeric() && lit.node.is_unsuffixed()) && local_has_implicit_ty(local) { - let mut visitor = LitVisitor::new(cx); - visitor.visit_expr(init); - // The type could be wildcard (`_`), therefore we need to include its span for suggestion. let span = if let Some(ty) = local.ty { local.pat.span.to(ty.span) @@ -25,31 +23,29 @@ pub(super) fn check_local<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'tcx> local.pat.span }; - if !visitor.unconstrained_lit_spans.is_empty() { - span_lint_and_then( - cx, - UNCONSTRAINED_NUMERIC_LITERAL, - span, - "type of this numeric variable is unconstrained", - |diag| { - let sugg = format!( - "{}: {}", - snippet_opt(cx, local.pat.span).unwrap_or("_".to_string()), - ty_suggestion(cx, init), - ); - diag.span_suggestion( - span, - "either add suffix to above numeric literal(s) or label the type explicitly", - sugg, - Applicability::MachineApplicable - ); - diag.span_note( - MultiSpan::from_spans(visitor.unconstrained_lit_spans), - "unconstrained numeric literals defined here", - ); - } - ); - } + span_lint_and_then( + cx, + UNCONSTRAINED_NUMERIC_LITERAL, + span, + "type of this numeric variable is unconstrained", + |diag| { + let sugg = format!( + "{}: {}", + snippet_opt(cx, local.pat.span).unwrap_or("_".to_string()), + ty_suggestion(cx, init), + ); + diag.span_suggestion( + span, + "either add suffix to above numeric literal(s) or label the type explicitly", + sugg, + Applicability::MachineApplicable + ); + diag.span_note( + lit.span, + "unconstrained numeric literals defined here", + ); + } + ); } } @@ -61,35 +57,6 @@ fn local_has_implicit_ty(local: &Local<'_>) -> bool { } } -struct LitVisitor<'hir, 'tcx> { - cx: &'hir LateContext<'tcx>, - unconstrained_lit_spans: Vec, -} - -impl<'hir, 'tcx> LitVisitor<'hir, 'tcx> { - fn new(cx: &'hir LateContext<'tcx>) -> Self { - Self { - cx, - unconstrained_lit_spans: vec![], - } - } -} - -impl<'hir, 'tcx> Visitor<'hir> for LitVisitor<'hir, 'tcx> { - fn visit_expr(&mut self, ex: &'hir Expr<'hir>) { - if let ExprKind::Lit(lit) = ex.kind { - if lit.node.is_numeric() && lit.node.is_unsuffixed() && !in_external_macro(self.cx.sess(), lit.span) { - self.unconstrained_lit_spans.push(lit.span); - } - } else { - walk_expr(self, ex); - } - } - - // Don't visit local in this visitor, `Local`s are handled in `check_local` call. - fn visit_local(&mut self, _: &'hir Local<'hir>) {} -} - fn ty_suggestion(cx: &LateContext<'_>, init: &Expr<'_>) -> String { let ty = cx.typeck_results().expr_ty(init); ty.to_string() diff --git a/tests/ui/guidelines/unconstrained_numeric_literal.fixed b/tests/ui/guidelines/unconstrained_numeric_literal.fixed index c3a0a3ec7eae..1ec003239d17 100644 --- a/tests/ui/guidelines/unconstrained_numeric_literal.fixed +++ b/tests/ui/guidelines/unconstrained_numeric_literal.fixed @@ -14,17 +14,6 @@ mod basic_expr { //~| NOTE: `-D clippy::unconstrained-numeric-literal` implied by `-D warnings` let x: f64 = 22.0; //~^ ERROR: type of this numeric variable is unconstrained - let x: [i32; 3] = [1, 2, 3]; - //~^ ERROR: type of this numeric variable is unconstrained - let x: (i32, i32) = if true { (1, 2) } else { (3, 4) }; - //~^ ERROR: type of this numeric variable is unconstrained - let x: (f64, i32, f64) = if true { (1.0, 2, 3.0) } else { (3.0, 4, 5.0) }; - //~^ ERROR: type of this numeric variable is unconstrained - let x: i32 = match 1 { - //~^ ERROR: type of this numeric variable is unconstrained - 1 => 1, - _ => 2, - }; // Has type annotation but it's a wildcard. let x: i32 = 1; //~^ ERROR: type of this numeric variable is unconstrained @@ -39,14 +28,7 @@ mod basic_expr { mod nested_local { fn test() { - let x: i32 = { - //~^ ERROR: type of this numeric variable is unconstrained - let y: i32 = 1; - //~^ ERROR: type of this numeric variable is unconstrained - 1 - }; - - let x: i32 = { + let x = { let y: i32 = 1; //~^ ERROR: type of this numeric variable is unconstrained 1 @@ -79,17 +61,4 @@ fn check_expect_suppression() { let x = 21; } -#[allow(clippy::useless_vec)] -fn check_vac_macro() { - let x: std::vec::Vec = vec![1, 2, 3]; - //~^ ERROR: type of this numeric variable is unconstrained - let x: std::vec::Vec = vec![1.0]; - //~^ ERROR: type of this numeric variable is unconstrained - - let y = vec![1_i32, 2_i32]; - let y = vec![0_u8, 1_u8]; - let y = vec![2.0_f64, 3.0_f64]; - let y: Vec = vec![1, 2]; -} - fn main() {} diff --git a/tests/ui/guidelines/unconstrained_numeric_literal.rs b/tests/ui/guidelines/unconstrained_numeric_literal.rs index b7269dc77ff1..8a5fa508cbc5 100644 --- a/tests/ui/guidelines/unconstrained_numeric_literal.rs +++ b/tests/ui/guidelines/unconstrained_numeric_literal.rs @@ -14,17 +14,6 @@ mod basic_expr { //~| NOTE: `-D clippy::unconstrained-numeric-literal` implied by `-D warnings` let x = 22.0; //~^ ERROR: type of this numeric variable is unconstrained - let x = [1, 2, 3]; - //~^ ERROR: type of this numeric variable is unconstrained - let x = if true { (1, 2) } else { (3, 4) }; - //~^ ERROR: type of this numeric variable is unconstrained - let x = if true { (1.0, 2, 3.0) } else { (3.0, 4, 5.0) }; - //~^ ERROR: type of this numeric variable is unconstrained - let x = match 1 { - //~^ ERROR: type of this numeric variable is unconstrained - 1 => 1, - _ => 2, - }; // Has type annotation but it's a wildcard. let x: _ = 1; //~^ ERROR: type of this numeric variable is unconstrained @@ -40,13 +29,6 @@ mod basic_expr { mod nested_local { fn test() { let x = { - //~^ ERROR: type of this numeric variable is unconstrained - let y = 1; - //~^ ERROR: type of this numeric variable is unconstrained - 1 - }; - - let x: i32 = { let y = 1; //~^ ERROR: type of this numeric variable is unconstrained 1 @@ -79,17 +61,4 @@ fn check_expect_suppression() { let x = 21; } -#[allow(clippy::useless_vec)] -fn check_vac_macro() { - let x = vec![1, 2, 3]; - //~^ ERROR: type of this numeric variable is unconstrained - let x = vec![1.0]; - //~^ ERROR: type of this numeric variable is unconstrained - - let y = vec![1_i32, 2_i32]; - let y = vec![0_u8, 1_u8]; - let y = vec![2.0_f64, 3.0_f64]; - let y: Vec = vec![1, 2]; -} - fn main() {} diff --git a/tests/ui/guidelines/unconstrained_numeric_literal.stderr b/tests/ui/guidelines/unconstrained_numeric_literal.stderr index 65372f1d15b5..db345edb6ab3 100644 --- a/tests/ui/guidelines/unconstrained_numeric_literal.stderr +++ b/tests/ui/guidelines/unconstrained_numeric_literal.stderr @@ -33,82 +33,13 @@ LL | let x: f64 = 22.0; | ~~~~~~ error: type of this numeric variable is unconstrained - --> $DIR/unconstrained_numeric_literal.rs:17:13 - | -LL | let x = [1, 2, 3]; - | ^ - | -note: unconstrained numeric literals defined here - --> $DIR/unconstrained_numeric_literal.rs:17:18 - | -LL | let x = [1, 2, 3]; - | ^ ^ ^ -help: either add suffix to above numeric literal(s) or label the type explicitly - | -LL | let x: [i32; 3] = [1, 2, 3]; - | ~~~~~~~~~~~ - -error: type of this numeric variable is unconstrained - --> $DIR/unconstrained_numeric_literal.rs:19:13 - | -LL | let x = if true { (1, 2) } else { (3, 4) }; - | ^ - | -note: unconstrained numeric literals defined here - --> $DIR/unconstrained_numeric_literal.rs:19:28 - | -LL | let x = if true { (1, 2) } else { (3, 4) }; - | ^ ^ ^ ^ -help: either add suffix to above numeric literal(s) or label the type explicitly - | -LL | let x: (i32, i32) = if true { (1, 2) } else { (3, 4) }; - | ~~~~~~~~~~~~~ - -error: type of this numeric variable is unconstrained - --> $DIR/unconstrained_numeric_literal.rs:21:13 - | -LL | let x = if true { (1.0, 2, 3.0) } else { (3.0, 4, 5.0) }; - | ^ - | -note: unconstrained numeric literals defined here - --> $DIR/unconstrained_numeric_literal.rs:21:28 - | -LL | let x = if true { (1.0, 2, 3.0) } else { (3.0, 4, 5.0) }; - | ^^^ ^ ^^^ ^^^ ^ ^^^ -help: either add suffix to above numeric literal(s) or label the type explicitly - | -LL | let x: (f64, i32, f64) = if true { (1.0, 2, 3.0) } else { (3.0, 4, 5.0) }; - | ~~~~~~~~~~~~~~~~~~ - -error: type of this numeric variable is unconstrained - --> $DIR/unconstrained_numeric_literal.rs:23:13 - | -LL | let x = match 1 { - | ^ - | -note: unconstrained numeric literals defined here - --> $DIR/unconstrained_numeric_literal.rs:23:23 - | -LL | let x = match 1 { - | ^ -LL | -LL | 1 => 1, - | ^ ^ -LL | _ => 2, - | ^ -help: either add suffix to above numeric literal(s) or label the type explicitly - | -LL | let x: i32 = match 1 { - | ~~~~~~ - -error: type of this numeric variable is unconstrained - --> $DIR/unconstrained_numeric_literal.rs:29:13 + --> $DIR/unconstrained_numeric_literal.rs:18:13 | LL | let x: _ = 1; | ^^^^ | note: unconstrained numeric literals defined here - --> $DIR/unconstrained_numeric_literal.rs:29:20 + --> $DIR/unconstrained_numeric_literal.rs:18:20 | LL | let x: _ = 1; | ^ @@ -118,29 +49,13 @@ LL | let x: i32 = 1; | ~~~~~~ error: type of this numeric variable is unconstrained - --> $DIR/unconstrained_numeric_literal.rs:42:13 - | -LL | let x = { - | ^ - | -note: unconstrained numeric literals defined here - --> $DIR/unconstrained_numeric_literal.rs:46:13 - | -LL | 1 - | ^ -help: either add suffix to above numeric literal(s) or label the type explicitly - | -LL | let x: i32 = { - | ~~~~~~ - -error: type of this numeric variable is unconstrained - --> $DIR/unconstrained_numeric_literal.rs:44:17 + --> $DIR/unconstrained_numeric_literal.rs:32:17 | LL | let y = 1; | ^ | note: unconstrained numeric literals defined here - --> $DIR/unconstrained_numeric_literal.rs:44:21 + --> $DIR/unconstrained_numeric_literal.rs:32:21 | LL | let y = 1; | ^ @@ -150,13 +65,13 @@ LL | let y: i32 = 1; | ~~~~~~ error: type of this numeric variable is unconstrained - --> $DIR/unconstrained_numeric_literal.rs:50:17 + --> $DIR/unconstrained_numeric_literal.rs:38:17 | LL | let y = 1; | ^ | note: unconstrained numeric literals defined here - --> $DIR/unconstrained_numeric_literal.rs:50:21 + --> $DIR/unconstrained_numeric_literal.rs:38:21 | LL | let y = 1; | ^ @@ -166,29 +81,13 @@ LL | let y: i32 = 1; | ~~~~~~ error: type of this numeric variable is unconstrained - --> $DIR/unconstrained_numeric_literal.rs:56:17 - | -LL | let y = 1; - | ^ - | -note: unconstrained numeric literals defined here - --> $DIR/unconstrained_numeric_literal.rs:56:21 - | -LL | let y = 1; - | ^ -help: either add suffix to above numeric literal(s) or label the type explicitly - | -LL | let y: i32 = 1; - | ~~~~~~ - -error: type of this numeric variable is unconstrained - --> $DIR/unconstrained_numeric_literal.rs:68:21 + --> $DIR/unconstrained_numeric_literal.rs:50:21 | LL | inline!(let x = 22;); | ^ | note: unconstrained numeric literals defined here - --> $DIR/unconstrained_numeric_literal.rs:68:25 + --> $DIR/unconstrained_numeric_literal.rs:50:25 | LL | inline!(let x = 22;); | ^^ @@ -198,37 +97,5 @@ help: either add suffix to above numeric literal(s) or label the type explicitly LL | inline!(let x: i32 = 22;); | ~~~~~~ -error: type of this numeric variable is unconstrained - --> $DIR/unconstrained_numeric_literal.rs:84:9 - | -LL | let x = vec![1, 2, 3]; - | ^ - | -note: unconstrained numeric literals defined here - --> $DIR/unconstrained_numeric_literal.rs:84:18 - | -LL | let x = vec![1, 2, 3]; - | ^ ^ ^ -help: either add suffix to above numeric literal(s) or label the type explicitly - | -LL | let x: std::vec::Vec = vec![1, 2, 3]; - | ~~~~~~~~~~~~~~~~~~~~~ - -error: type of this numeric variable is unconstrained - --> $DIR/unconstrained_numeric_literal.rs:86:9 - | -LL | let x = vec![1.0]; - | ^ - | -note: unconstrained numeric literals defined here - --> $DIR/unconstrained_numeric_literal.rs:86:18 - | -LL | let x = vec![1.0]; - | ^^^ -help: either add suffix to above numeric literal(s) or label the type explicitly - | -LL | let x: std::vec::Vec = vec![1.0]; - | ~~~~~~~~~~~~~~~~~~~~~ - -error: aborting due to 14 previous errors +error: aborting due to 6 previous errors