From 1612dd859e22f9338f95553fcbcf6701feb12309 Mon Sep 17 00:00:00 2001 From: Catherine <114838443+Centri3@users.noreply.github.com> Date: Tue, 20 Jun 2023 16:34:24 -0500 Subject: [PATCH 1/4] new lint `legacy_integral_constants` --- CHANGELOG.md | 1 + .../src/casts/cast_possible_truncation.rs | 4 +- clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/implicit_saturating_add.rs | 24 +-- clippy_lints/src/legacy_integral_constants.rs | 147 ++++++++++++++++++ clippy_lints/src/lib.rs | 2 + clippy_utils/src/msrvs.rs | 2 +- tests/ui/checked_conversions.fixed | 1 + tests/ui/checked_conversions.rs | 1 + tests/ui/checked_conversions.stderr | 34 ++-- tests/ui/legacy_integral_constants.fixed | 33 ++++ tests/ui/legacy_integral_constants.rs | 33 ++++ tests/ui/legacy_integral_constants.stderr | 72 +++++++++ tests/ui/manual_saturating_arithmetic.fixed | 2 +- tests/ui/manual_saturating_arithmetic.rs | 2 +- tests/ui/suspicious_arithmetic_impl.rs | 1 + tests/ui/suspicious_arithmetic_impl.stderr | 18 +-- 17 files changed, 335 insertions(+), 43 deletions(-) create mode 100644 clippy_lints/src/legacy_integral_constants.rs create mode 100644 tests/ui/legacy_integral_constants.fixed create mode 100644 tests/ui/legacy_integral_constants.rs create mode 100644 tests/ui/legacy_integral_constants.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 71671273c57b..11dbece50b76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4956,6 +4956,7 @@ Released 2018-09-13 [`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays [`large_stack_frames`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames [`large_types_passed_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value +[`legacy_integral_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#legacy_integral_constants [`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty [`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero [`let_and_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return diff --git a/clippy_lints/src/casts/cast_possible_truncation.rs b/clippy_lints/src/casts/cast_possible_truncation.rs index 84b99ad5c243..b41be81f3ff1 100644 --- a/clippy_lints/src/casts/cast_possible_truncation.rs +++ b/clippy_lints/src/casts/cast_possible_truncation.rs @@ -41,7 +41,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b }) }, BinOpKind::Rem | BinOpKind::BitAnd => get_constant_bits(cx, right) - .unwrap_or(u64::max_value()) + .unwrap_or(u64::MAX) .min(apply_reductions(cx, nbits, left, signed)), BinOpKind::Shr => apply_reductions(cx, nbits, left, signed) .saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).expect("shift too high"))), @@ -56,7 +56,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b } else { None }; - apply_reductions(cx, nbits, left, signed).min(max_bits.unwrap_or(u64::max_value())) + apply_reductions(cx, nbits, left, signed).min(max_bits.unwrap_or(u64::MAX)) }, ExprKind::MethodCall(method, _, [lo, hi], _) => { if method.ident.as_str() == "clamp" { diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index db114abfc869..2687d3f04428 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -234,6 +234,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::large_include_file::LARGE_INCLUDE_FILE_INFO, crate::large_stack_arrays::LARGE_STACK_ARRAYS_INFO, crate::large_stack_frames::LARGE_STACK_FRAMES_INFO, + crate::legacy_integral_constants::LEGACY_INTEGRAL_CONSTANTS_INFO, crate::len_zero::COMPARISON_TO_EMPTY_INFO, crate::len_zero::LEN_WITHOUT_IS_EMPTY_INFO, crate::len_zero::LEN_ZERO_INFO, diff --git a/clippy_lints/src/implicit_saturating_add.rs b/clippy_lints/src/implicit_saturating_add.rs index ee7973b82ab9..6bd15118b42c 100644 --- a/clippy_lints/src/implicit_saturating_add.rs +++ b/clippy_lints/src/implicit_saturating_add.rs @@ -82,18 +82,18 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingAdd { fn get_int_max(ty: Ty<'_>) -> Option { match ty.peel_refs().kind() { - Int(IntTy::I8) => i8::max_value().try_into().ok(), - Int(IntTy::I16) => i16::max_value().try_into().ok(), - Int(IntTy::I32) => i32::max_value().try_into().ok(), - Int(IntTy::I64) => i64::max_value().try_into().ok(), - Int(IntTy::I128) => i128::max_value().try_into().ok(), - Int(IntTy::Isize) => isize::max_value().try_into().ok(), - Uint(UintTy::U8) => u8::max_value().try_into().ok(), - Uint(UintTy::U16) => u16::max_value().try_into().ok(), - Uint(UintTy::U32) => u32::max_value().try_into().ok(), - Uint(UintTy::U64) => u64::max_value().try_into().ok(), - Uint(UintTy::U128) => Some(u128::max_value()), - Uint(UintTy::Usize) => usize::max_value().try_into().ok(), + Int(IntTy::I8) => i8::MAX.try_into().ok(), + Int(IntTy::I16) => i16::MAX.try_into().ok(), + Int(IntTy::I32) => i32::MAX.try_into().ok(), + Int(IntTy::I64) => i64::MAX.try_into().ok(), + Int(IntTy::I128) => i128::MAX.try_into().ok(), + Int(IntTy::Isize) => isize::MAX.try_into().ok(), + Uint(UintTy::U8) => u8::MAX.try_into().ok(), + Uint(UintTy::U16) => u16::MAX.try_into().ok(), + Uint(UintTy::U32) => u32::MAX.try_into().ok(), + Uint(UintTy::U64) => u64::MAX.try_into().ok(), + Uint(UintTy::U128) => Some(u128::MAX), + Uint(UintTy::Usize) => usize::MAX.try_into().ok(), _ => None, } } diff --git a/clippy_lints/src/legacy_integral_constants.rs b/clippy_lints/src/legacy_integral_constants.rs new file mode 100644 index 000000000000..92301ae181d9 --- /dev/null +++ b/clippy_lints/src/legacy_integral_constants.rs @@ -0,0 +1,147 @@ +use clippy_utils::{ + diagnostics::span_lint_and_then, + get_parent_expr, is_from_proc_macro, last_path_segment, + msrvs::{self, Msrv}, + std_or_core, +}; +use rustc_errors::Applicability; +use rustc_hir::{def::Res, def_id::DefId}; +use rustc_hir::{Expr, ExprKind, PrimTy, QPath, TyKind}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::lint::in_external_macro; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::{sym, Symbol}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of `::max_value()`, `std::::MAX`, + /// `std::::EPSILON`, etc. + /// + /// ### Why is this bad? + /// All of these have been superceded by the associated constants on their respective types, + /// such as `i128::MAX`. These legacy constants may be deprecated in a future version of rust. + /// + /// ### Example + /// ```rust + /// let eps = std::f32::EPSILON; + /// ``` + /// Use instead: + /// ```rust + /// let eps = f32::EPSILON; + /// ``` + #[clippy::version = "1.72.0"] + pub LEGACY_INTEGRAL_CONSTANTS, + style, + "checks for usage of legacy std integral constants" +} +pub struct LegacyIntegralConstants { + msrv: Msrv, +} + +impl LegacyIntegralConstants { + #[must_use] + pub fn new(msrv: Msrv) -> Self { + Self { msrv } + } +} + +impl_lint_pass!(LegacyIntegralConstants => [LEGACY_INTEGRAL_CONSTANTS]); + +impl<'tcx> LateLintPass<'tcx> for LegacyIntegralConstants { + fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { + if !self.msrv.meets(msrvs::STD_INTEGRAL_CONSTANTS) || in_external_macro(cx.sess(), expr.span) { + return; + } + let ExprKind::Path(qpath) = expr.kind else { + return; + }; + + // `std::::` check + let (span, sugg, is_method, needs_reexported_primitive) = if let QPath::Resolved(_, path) = qpath + && let Some(def_id) = path.res.opt_def_id() + && let Some(name) = path.segments.iter().last().map(|segment| segment.ident.name) + && let Some(module_name) = is_path_in_integral_module(cx, def_id) + { + ( + expr.span, + format!("{module_name}::{name}"), + false, + path.segments.get(0).is_some_and(|segment| segment.ident.name == module_name) + ) + // `::xxx_value` check + } else if let QPath::TypeRelative(ty, _) = qpath + && let TyKind::Path(ty_qpath) = ty.kind + && let Res::PrimTy(PrimTy::Int(_) | PrimTy::Uint(_)) = cx.qpath_res(&ty_qpath, ty.hir_id) + && let last_segment = last_path_segment(&qpath) + && let name = last_segment.ident.name.as_str() + && (name == "max_value" || name == "min_value") + // Also remove the `()` + && let Some(par_expr) = get_parent_expr(cx, expr) + && let ExprKind::Call(_, _) = par_expr.kind + { + ( + qpath.last_segment_span().with_hi(par_expr.span.hi()), + name[..=2].to_ascii_uppercase(), + true, + false, + ) + } else { + return; + }; + + if !is_from_proc_macro(cx, expr) { + let msg = if is_method { + "usage of a legacy integral constant method" + } else { + "usage of a legacy integral constant" + }; + + span_lint_and_then(cx, LEGACY_INTEGRAL_CONSTANTS, span, msg, |diag| { + // Add `std::primitive` if necessary + let new_sugg = if needs_reexported_primitive + && let Some(std_or_core) = std_or_core(cx) + { + format!("{std_or_core}::primitive::{sugg}") + } else { + sugg.clone() + }; + diag.span_suggestion(span, "try", new_sugg, Applicability::MachineApplicable); + // If we added `std::primitive`, also suggest without it + if needs_reexported_primitive && let Some((module_name, _)) = sugg.split_once("::") { + diag.note(format!( + "if you remove the `use` statement that introduces `{module_name}`, using the above is \ + unnecessary", + )); + } + }); + } + } + + extract_msrv_attr!(LateContext); +} + +fn is_path_in_integral_module(cx: &LateContext<'_>, def_id: DefId) -> Option { + if let [ + sym::core, + module @ (sym::u8 + | sym::i8 + | sym::u16 + | sym::i16 + | sym::u32 + | sym::i32 + | sym::u64 + | sym::i64 + | sym::u128 + | sym::i128 + | sym::usize + | sym::isize + | sym::f32 + | sym::f64), + _, + ] = &*cx.get_def_path(def_id) + { + return Some(*module); + } + + None +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 358004cf460b..d65005aa59a7 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -173,6 +173,7 @@ mod large_futures; mod large_include_file; mod large_stack_arrays; mod large_stack_frames; +mod legacy_integral_constants; mod len_zero; mod let_if_seq; mod let_underscore; @@ -1079,6 +1080,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: needless_raw_string_hashes_allow_one, }) }); + store.register_late_pass(move |_| Box::new(legacy_integral_constants::LegacyIntegralConstants::new(msrv()))); store.register_late_pass(|_| Box::new(manual_range_patterns::ManualRangePatterns)); store.register_early_pass(|| Box::new(visibility::Visibility)); store.register_late_pass(move |_| Box::new(tuple_array_conversions::TupleArrayConversions { msrv: msrv() })); diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 3637476c4087..41f4e634b402 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -33,7 +33,7 @@ msrv_aliases! { 1,47,0 { TAU, IS_ASCII_DIGIT_CONST, ARRAY_IMPL_ANY_LEN } 1,46,0 { CONST_IF_MATCH } 1,45,0 { STR_STRIP_PREFIX } - 1,43,0 { LOG2_10, LOG10_2 } + 1,43,0 { LOG2_10, LOG10_2, STD_INTEGRAL_CONSTANTS } 1,42,0 { MATCHES_MACRO, SLICE_PATTERNS, PTR_SLICE_RAW_PARTS } 1,41,0 { RE_REBALANCING_COHERENCE, RESULT_MAP_OR_ELSE } 1,40,0 { MEM_TAKE, NON_EXHAUSTIVE, OPTION_AS_DEREF } diff --git a/tests/ui/checked_conversions.fixed b/tests/ui/checked_conversions.fixed index 188e6d975952..e9aca5b3a386 100644 --- a/tests/ui/checked_conversions.fixed +++ b/tests/ui/checked_conversions.fixed @@ -2,6 +2,7 @@ #![allow( clippy::cast_lossless, + clippy::legacy_integral_constants, unused, // Int::max_value will be deprecated in the future deprecated, diff --git a/tests/ui/checked_conversions.rs b/tests/ui/checked_conversions.rs index 70f0f0975acd..645391e52acc 100644 --- a/tests/ui/checked_conversions.rs +++ b/tests/ui/checked_conversions.rs @@ -2,6 +2,7 @@ #![allow( clippy::cast_lossless, + clippy::legacy_integral_constants, unused, // Int::max_value will be deprecated in the future deprecated, diff --git a/tests/ui/checked_conversions.stderr b/tests/ui/checked_conversions.stderr index 273ead73bda5..b844891d30f6 100644 --- a/tests/ui/checked_conversions.stderr +++ b/tests/ui/checked_conversions.stderr @@ -1,5 +1,5 @@ error: checked cast can be simplified - --> $DIR/checked_conversions.rs:16:13 + --> $DIR/checked_conversions.rs:17:13 | LL | let _ = value <= (u32::max_value() as i64) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()` @@ -7,97 +7,97 @@ LL | let _ = value <= (u32::max_value() as i64) && value >= 0; = note: `-D clippy::checked-conversions` implied by `-D warnings` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:17:13 + --> $DIR/checked_conversions.rs:18:13 | LL | let _ = value <= (u32::MAX as i64) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:21:13 + --> $DIR/checked_conversions.rs:22:13 | LL | let _ = value <= i64::from(u16::max_value()) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:22:13 + --> $DIR/checked_conversions.rs:23:13 | LL | let _ = value <= i64::from(u16::MAX) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:26:13 + --> $DIR/checked_conversions.rs:27:13 | LL | let _ = value <= (u8::max_value() as isize) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:27:13 + --> $DIR/checked_conversions.rs:28:13 | LL | let _ = value <= (u8::MAX as isize) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:33:13 + --> $DIR/checked_conversions.rs:34:13 | LL | let _ = value <= (i32::max_value() as i64) && value >= (i32::min_value() as i64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:34:13 + --> $DIR/checked_conversions.rs:35:13 | LL | let _ = value <= (i32::MAX as i64) && value >= (i32::MIN as i64); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:38:13 + --> $DIR/checked_conversions.rs:39:13 | LL | let _ = value <= i64::from(i16::max_value()) && value >= i64::from(i16::min_value()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:39:13 + --> $DIR/checked_conversions.rs:40:13 | LL | let _ = value <= i64::from(i16::MAX) && value >= i64::from(i16::MIN); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:45:13 + --> $DIR/checked_conversions.rs:46:13 | LL | let _ = value <= i32::max_value() as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:46:13 + --> $DIR/checked_conversions.rs:47:13 | LL | let _ = value <= i32::MAX as u32; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:50:13 + --> $DIR/checked_conversions.rs:51:13 | LL | let _ = value <= isize::max_value() as usize && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:51:13 + --> $DIR/checked_conversions.rs:52:13 | LL | let _ = value <= isize::MAX as usize && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:55:13 + --> $DIR/checked_conversions.rs:56:13 | LL | let _ = value <= u16::max_value() as u32 && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:56:13 + --> $DIR/checked_conversions.rs:57:13 | LL | let _ = value <= u16::MAX as u32 && value as i32 == 5; | ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()` error: checked cast can be simplified - --> $DIR/checked_conversions.rs:89:13 + --> $DIR/checked_conversions.rs:90:13 | LL | let _ = value <= (u32::MAX as i64) && value >= 0; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()` diff --git a/tests/ui/legacy_integral_constants.fixed b/tests/ui/legacy_integral_constants.fixed new file mode 100644 index 000000000000..c1df2f8a8e59 --- /dev/null +++ b/tests/ui/legacy_integral_constants.fixed @@ -0,0 +1,33 @@ +//@run-rustfix +//@aux-build:proc_macros.rs +#![allow(clippy::no_effect, deprecated, unused)] +#![warn(clippy::legacy_integral_constants)] + +#[macro_use] +extern crate proc_macros; + +fn main() { + f32::EPSILON; + u8::MIN; + usize::MIN; + u32::MAX; + use std::u32::MAX; + u32::MAX; + u32::MAX; + u8::MAX; + u8::MIN; + ::std::primitive::u8::MIN; + ::std::u8::MIN; + ::std::primitive::u8::MIN; + std::primitive::u32::MAX; + use std::f64; + std::primitive::f64::MAX; + // Don't lint + f32::EPSILON; + u8::MIN; + external! { + ::std::primitive::u8::MIN; + ::std::u8::MIN; + ::std::primitive::u8::min_value(); + } +} diff --git a/tests/ui/legacy_integral_constants.rs b/tests/ui/legacy_integral_constants.rs new file mode 100644 index 000000000000..3067586b8f5b --- /dev/null +++ b/tests/ui/legacy_integral_constants.rs @@ -0,0 +1,33 @@ +//@run-rustfix +//@aux-build:proc_macros.rs +#![allow(clippy::no_effect, deprecated, unused)] +#![warn(clippy::legacy_integral_constants)] + +#[macro_use] +extern crate proc_macros; + +fn main() { + std::f32::EPSILON; + std::u8::MIN; + std::usize::MIN; + std::u32::MAX; + use std::u32::MAX; + MAX; + u32::max_value(); + u8::max_value(); + u8::min_value(); + ::std::primitive::u8::MIN; + ::std::u8::MIN; + ::std::primitive::u8::min_value(); + std::primitive::u32::max_value(); + use std::f64; + f64::MAX; + // Don't lint + f32::EPSILON; + u8::MIN; + external! { + ::std::primitive::u8::MIN; + ::std::u8::MIN; + ::std::primitive::u8::min_value(); + } +} diff --git a/tests/ui/legacy_integral_constants.stderr b/tests/ui/legacy_integral_constants.stderr new file mode 100644 index 000000000000..62e69b0d1985 --- /dev/null +++ b/tests/ui/legacy_integral_constants.stderr @@ -0,0 +1,72 @@ +error: usage of a legacy integral constant + --> $DIR/legacy_integral_constants.rs:10:5 + | +LL | std::f32::EPSILON; + | ^^^^^^^^^^^^^^^^^ help: try: `f32::EPSILON` + | + = note: `-D clippy::legacy-integral-constants` implied by `-D warnings` + +error: usage of a legacy integral constant + --> $DIR/legacy_integral_constants.rs:11:5 + | +LL | std::u8::MIN; + | ^^^^^^^^^^^^ help: try: `u8::MIN` + +error: usage of a legacy integral constant + --> $DIR/legacy_integral_constants.rs:12:5 + | +LL | std::usize::MIN; + | ^^^^^^^^^^^^^^^ help: try: `usize::MIN` + +error: usage of a legacy integral constant + --> $DIR/legacy_integral_constants.rs:13:5 + | +LL | std::u32::MAX; + | ^^^^^^^^^^^^^ help: try: `u32::MAX` + +error: usage of a legacy integral constant + --> $DIR/legacy_integral_constants.rs:15:5 + | +LL | MAX; + | ^^^ help: try: `u32::MAX` + +error: usage of a legacy integral constant method + --> $DIR/legacy_integral_constants.rs:16:10 + | +LL | u32::max_value(); + | ^^^^^^^^^^^ help: try: `MAX` + +error: usage of a legacy integral constant method + --> $DIR/legacy_integral_constants.rs:17:9 + | +LL | u8::max_value(); + | ^^^^^^^^^^^ help: try: `MAX` + +error: usage of a legacy integral constant method + --> $DIR/legacy_integral_constants.rs:18:9 + | +LL | u8::min_value(); + | ^^^^^^^^^^^ help: try: `MIN` + +error: usage of a legacy integral constant method + --> $DIR/legacy_integral_constants.rs:21:27 + | +LL | ::std::primitive::u8::min_value(); + | ^^^^^^^^^^^ help: try: `MIN` + +error: usage of a legacy integral constant method + --> $DIR/legacy_integral_constants.rs:22:26 + | +LL | std::primitive::u32::max_value(); + | ^^^^^^^^^^^ help: try: `MAX` + +error: usage of a legacy integral constant + --> $DIR/legacy_integral_constants.rs:24:5 + | +LL | f64::MAX; + | ^^^^^^^^ help: try: `std::primitive::f64::MAX` + | + = note: if you remove the `use` statement that introduces `f64`, using the above is unnecessary + +error: aborting due to 11 previous errors + diff --git a/tests/ui/manual_saturating_arithmetic.fixed b/tests/ui/manual_saturating_arithmetic.fixed index 7dd4521fa78e..ca1b89e65c8f 100644 --- a/tests/ui/manual_saturating_arithmetic.fixed +++ b/tests/ui/manual_saturating_arithmetic.fixed @@ -1,6 +1,6 @@ //@run-rustfix -#![allow(unused_imports)] +#![allow(clippy::legacy_integral_constants, unused_imports)] use std::{i128, i32, u128, u32}; diff --git a/tests/ui/manual_saturating_arithmetic.rs b/tests/ui/manual_saturating_arithmetic.rs index 463ee0692899..8e7cd8d75f01 100644 --- a/tests/ui/manual_saturating_arithmetic.rs +++ b/tests/ui/manual_saturating_arithmetic.rs @@ -1,6 +1,6 @@ //@run-rustfix -#![allow(unused_imports)] +#![allow(clippy::legacy_integral_constants, unused_imports)] use std::{i128, i32, u128, u32}; diff --git a/tests/ui/suspicious_arithmetic_impl.rs b/tests/ui/suspicious_arithmetic_impl.rs index ae253a0487cb..07cc023d608b 100644 --- a/tests/ui/suspicious_arithmetic_impl.rs +++ b/tests/ui/suspicious_arithmetic_impl.rs @@ -1,3 +1,4 @@ +#![allow(clippy::legacy_integral_constants)] #![warn(clippy::suspicious_arithmetic_impl)] use std::ops::{ Add, AddAssign, BitAnd, BitOr, BitOrAssign, BitXor, Div, DivAssign, Mul, MulAssign, Rem, Shl, Shr, Sub, diff --git a/tests/ui/suspicious_arithmetic_impl.stderr b/tests/ui/suspicious_arithmetic_impl.stderr index ced1305874e5..2b069f1e2e75 100644 --- a/tests/ui/suspicious_arithmetic_impl.stderr +++ b/tests/ui/suspicious_arithmetic_impl.stderr @@ -1,5 +1,5 @@ error: suspicious use of `-` in `Add` impl - --> $DIR/suspicious_arithmetic_impl.rs:13:20 + --> $DIR/suspicious_arithmetic_impl.rs:14:20 | LL | Foo(self.0 - other.0) | ^ @@ -7,7 +7,7 @@ LL | Foo(self.0 - other.0) = note: `-D clippy::suspicious-arithmetic-impl` implied by `-D warnings` error: suspicious use of `-` in `AddAssign` impl - --> $DIR/suspicious_arithmetic_impl.rs:19:23 + --> $DIR/suspicious_arithmetic_impl.rs:20:23 | LL | *self = *self - other; | ^ @@ -15,43 +15,43 @@ LL | *self = *self - other; = note: `-D clippy::suspicious-op-assign-impl` implied by `-D warnings` error: suspicious use of `/` in `MulAssign` impl - --> $DIR/suspicious_arithmetic_impl.rs:32:16 + --> $DIR/suspicious_arithmetic_impl.rs:33:16 | LL | self.0 /= other.0; | ^^ error: suspicious use of `/` in `Rem` impl - --> $DIR/suspicious_arithmetic_impl.rs:70:20 + --> $DIR/suspicious_arithmetic_impl.rs:71:20 | LL | Foo(self.0 / other.0) | ^ error: suspicious use of `|` in `BitAnd` impl - --> $DIR/suspicious_arithmetic_impl.rs:78:20 + --> $DIR/suspicious_arithmetic_impl.rs:79:20 | LL | Foo(self.0 | other.0) | ^ error: suspicious use of `^` in `BitOr` impl - --> $DIR/suspicious_arithmetic_impl.rs:86:20 + --> $DIR/suspicious_arithmetic_impl.rs:87:20 | LL | Foo(self.0 ^ other.0) | ^ error: suspicious use of `&` in `BitXor` impl - --> $DIR/suspicious_arithmetic_impl.rs:94:20 + --> $DIR/suspicious_arithmetic_impl.rs:95:20 | LL | Foo(self.0 & other.0) | ^ error: suspicious use of `>>` in `Shl` impl - --> $DIR/suspicious_arithmetic_impl.rs:102:20 + --> $DIR/suspicious_arithmetic_impl.rs:103:20 | LL | Foo(self.0 >> other.0) | ^^ error: suspicious use of `<<` in `Shr` impl - --> $DIR/suspicious_arithmetic_impl.rs:110:20 + --> $DIR/suspicious_arithmetic_impl.rs:111:20 | LL | Foo(self.0 << other.0) | ^^ From d5c15a464ee8f3fe9e84ffcece04e276578b46d7 Mon Sep 17 00:00:00 2001 From: Catherine <114838443+Centri3@users.noreply.github.com> Date: Thu, 22 Jun 2023 19:03:25 -0500 Subject: [PATCH 2/4] now mentions `use` statements to remove --- CHANGELOG.md | 2 +- clippy_lints/src/declared_lints.rs | 2 +- clippy_lints/src/legacy_integral_constants.rs | 147 ------------ clippy_lints/src/legacy_numeric_constants.rs | 227 ++++++++++++++++++ clippy_lints/src/lib.rs | 2 +- tests/compile-test.rs | 1 + tests/ui/checked_conversions.fixed | 2 +- tests/ui/checked_conversions.rs | 2 +- tests/ui/legacy_integral_constants.fixed | 33 --- tests/ui/legacy_integral_constants.stderr | 72 ------ ...nstants.rs => legacy_numeric_constants.rs} | 27 ++- tests/ui/legacy_numeric_constants.stderr | 124 ++++++++++ tests/ui/manual_saturating_arithmetic.fixed | 2 +- tests/ui/manual_saturating_arithmetic.rs | 2 +- tests/ui/suspicious_arithmetic_impl.rs | 2 +- 15 files changed, 385 insertions(+), 262 deletions(-) delete mode 100644 clippy_lints/src/legacy_integral_constants.rs create mode 100644 clippy_lints/src/legacy_numeric_constants.rs delete mode 100644 tests/ui/legacy_integral_constants.fixed delete mode 100644 tests/ui/legacy_integral_constants.stderr rename tests/ui/{legacy_integral_constants.rs => legacy_numeric_constants.rs} (59%) create mode 100644 tests/ui/legacy_numeric_constants.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 11dbece50b76..de681b488f39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4956,7 +4956,7 @@ Released 2018-09-13 [`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays [`large_stack_frames`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames [`large_types_passed_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value -[`legacy_integral_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#legacy_integral_constants +[`legacy_numeric_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#legacy_numeric_constants [`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty [`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero [`let_and_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 2687d3f04428..e42255f25bef 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -234,7 +234,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[ crate::large_include_file::LARGE_INCLUDE_FILE_INFO, crate::large_stack_arrays::LARGE_STACK_ARRAYS_INFO, crate::large_stack_frames::LARGE_STACK_FRAMES_INFO, - crate::legacy_integral_constants::LEGACY_INTEGRAL_CONSTANTS_INFO, + crate::legacy_numeric_constants::LEGACY_NUMERIC_CONSTANTS_INFO, crate::len_zero::COMPARISON_TO_EMPTY_INFO, crate::len_zero::LEN_WITHOUT_IS_EMPTY_INFO, crate::len_zero::LEN_ZERO_INFO, diff --git a/clippy_lints/src/legacy_integral_constants.rs b/clippy_lints/src/legacy_integral_constants.rs deleted file mode 100644 index 92301ae181d9..000000000000 --- a/clippy_lints/src/legacy_integral_constants.rs +++ /dev/null @@ -1,147 +0,0 @@ -use clippy_utils::{ - diagnostics::span_lint_and_then, - get_parent_expr, is_from_proc_macro, last_path_segment, - msrvs::{self, Msrv}, - std_or_core, -}; -use rustc_errors::Applicability; -use rustc_hir::{def::Res, def_id::DefId}; -use rustc_hir::{Expr, ExprKind, PrimTy, QPath, TyKind}; -use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::lint::in_external_macro; -use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{sym, Symbol}; - -declare_clippy_lint! { - /// ### What it does - /// Checks for usage of `::max_value()`, `std::::MAX`, - /// `std::::EPSILON`, etc. - /// - /// ### Why is this bad? - /// All of these have been superceded by the associated constants on their respective types, - /// such as `i128::MAX`. These legacy constants may be deprecated in a future version of rust. - /// - /// ### Example - /// ```rust - /// let eps = std::f32::EPSILON; - /// ``` - /// Use instead: - /// ```rust - /// let eps = f32::EPSILON; - /// ``` - #[clippy::version = "1.72.0"] - pub LEGACY_INTEGRAL_CONSTANTS, - style, - "checks for usage of legacy std integral constants" -} -pub struct LegacyIntegralConstants { - msrv: Msrv, -} - -impl LegacyIntegralConstants { - #[must_use] - pub fn new(msrv: Msrv) -> Self { - Self { msrv } - } -} - -impl_lint_pass!(LegacyIntegralConstants => [LEGACY_INTEGRAL_CONSTANTS]); - -impl<'tcx> LateLintPass<'tcx> for LegacyIntegralConstants { - fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) { - if !self.msrv.meets(msrvs::STD_INTEGRAL_CONSTANTS) || in_external_macro(cx.sess(), expr.span) { - return; - } - let ExprKind::Path(qpath) = expr.kind else { - return; - }; - - // `std::::` check - let (span, sugg, is_method, needs_reexported_primitive) = if let QPath::Resolved(_, path) = qpath - && let Some(def_id) = path.res.opt_def_id() - && let Some(name) = path.segments.iter().last().map(|segment| segment.ident.name) - && let Some(module_name) = is_path_in_integral_module(cx, def_id) - { - ( - expr.span, - format!("{module_name}::{name}"), - false, - path.segments.get(0).is_some_and(|segment| segment.ident.name == module_name) - ) - // `::xxx_value` check - } else if let QPath::TypeRelative(ty, _) = qpath - && let TyKind::Path(ty_qpath) = ty.kind - && let Res::PrimTy(PrimTy::Int(_) | PrimTy::Uint(_)) = cx.qpath_res(&ty_qpath, ty.hir_id) - && let last_segment = last_path_segment(&qpath) - && let name = last_segment.ident.name.as_str() - && (name == "max_value" || name == "min_value") - // Also remove the `()` - && let Some(par_expr) = get_parent_expr(cx, expr) - && let ExprKind::Call(_, _) = par_expr.kind - { - ( - qpath.last_segment_span().with_hi(par_expr.span.hi()), - name[..=2].to_ascii_uppercase(), - true, - false, - ) - } else { - return; - }; - - if !is_from_proc_macro(cx, expr) { - let msg = if is_method { - "usage of a legacy integral constant method" - } else { - "usage of a legacy integral constant" - }; - - span_lint_and_then(cx, LEGACY_INTEGRAL_CONSTANTS, span, msg, |diag| { - // Add `std::primitive` if necessary - let new_sugg = if needs_reexported_primitive - && let Some(std_or_core) = std_or_core(cx) - { - format!("{std_or_core}::primitive::{sugg}") - } else { - sugg.clone() - }; - diag.span_suggestion(span, "try", new_sugg, Applicability::MachineApplicable); - // If we added `std::primitive`, also suggest without it - if needs_reexported_primitive && let Some((module_name, _)) = sugg.split_once("::") { - diag.note(format!( - "if you remove the `use` statement that introduces `{module_name}`, using the above is \ - unnecessary", - )); - } - }); - } - } - - extract_msrv_attr!(LateContext); -} - -fn is_path_in_integral_module(cx: &LateContext<'_>, def_id: DefId) -> Option { - if let [ - sym::core, - module @ (sym::u8 - | sym::i8 - | sym::u16 - | sym::i16 - | sym::u32 - | sym::i32 - | sym::u64 - | sym::i64 - | sym::u128 - | sym::i128 - | sym::usize - | sym::isize - | sym::f32 - | sym::f64), - _, - ] = &*cx.get_def_path(def_id) - { - return Some(*module); - } - - None -} diff --git a/clippy_lints/src/legacy_numeric_constants.rs b/clippy_lints/src/legacy_numeric_constants.rs new file mode 100644 index 000000000000..b5999a996d5e --- /dev/null +++ b/clippy_lints/src/legacy_numeric_constants.rs @@ -0,0 +1,227 @@ +use clippy_utils::{ + diagnostics::span_lint_and_then, + get_parent_expr, is_from_proc_macro, last_path_segment, + msrvs::{self, Msrv}, +}; +use itertools::Itertools; +use rustc_data_structures::fx::FxHashMap; +use rustc_errors::Applicability; +use rustc_hir::{ + def::Res, + def_id::DefId, + intravisit::{walk_expr, Visitor}, + Item, UseKind, +}; +use rustc_hir::{Expr, ExprKind, ItemKind, PrimTy, QPath, TyKind}; +use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::{hir::nested_filter::OnlyBodies, lint::in_external_macro}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::{sym, Span, Symbol}; + +declare_clippy_lint! { + /// ### What it does + /// Checks for usage of `::max_value()`, `std::::MAX`, + /// `std::::EPSILON`, etc. + /// + /// ### Why is this bad? + /// All of these have been superceded by the associated constants on their respective types, + /// such as `i128::MAX`. These legacy constants may be deprecated in a future version of rust. + /// + /// ### Example + /// ```rust + /// let eps = std::f32::EPSILON; + /// ``` + /// Use instead: + /// ```rust + /// let eps = f32::EPSILON; + /// ``` + #[clippy::version = "1.72.0"] + pub LEGACY_NUMERIC_CONSTANTS, + style, + "checks for usage of legacy std numeric constants and methods" +} +pub struct LegacyNumericConstants { + msrv: Msrv, + use_stmts: FxHashMap>, + glob_use_stmts: Vec, +} + +impl LegacyNumericConstants { + #[must_use] + pub fn new(msrv: Msrv) -> Self { + Self { + msrv, + use_stmts: FxHashMap::default(), + glob_use_stmts: vec![], + } + } +} + +impl_lint_pass!(LegacyNumericConstants => [LEGACY_NUMERIC_CONSTANTS]); + +impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants { + fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { + let Self { + msrv: _, + use_stmts, + glob_use_stmts, + } = self; + + if !item.span.is_dummy() && let ItemKind::Use(path, kind) = item.kind { + match kind { + UseKind::Single => { + for res in &path.res { + if let Some(def_id) = res.opt_def_id() + && let Some(module_name) = is_path_in_integral_module(cx, def_id) + && let _ = use_stmts.insert(module_name, vec![]) + && let Some(use_stmts) = use_stmts.get_mut(&module_name) + { + use_stmts.push(item.span); + } + } + }, + UseKind::Glob => glob_use_stmts.push(item.span), + UseKind::ListStem => {}, + } + } + } + + fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { + let Self { + msrv, + use_stmts, + glob_use_stmts, + } = self; + + let mut v = V { + cx, + msrv, + use_stmts, + glob_use_stmts, + }; + cx.tcx.hir().visit_all_item_likes_in_crate(&mut v); + } + + extract_msrv_attr!(LateContext); +} + +struct V<'a, 'tcx> { + cx: &'a LateContext<'tcx>, + msrv: &'a Msrv, + use_stmts: &'a FxHashMap>, + glob_use_stmts: &'a Vec, +} + +impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> { + type NestedFilter = OnlyBodies; + + fn nested_visit_map(&mut self) -> Self::Map { + self.cx.tcx.hir() + } + + fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { + walk_expr(self, expr); + let Self { + cx, + msrv, + use_stmts, + glob_use_stmts, + } = *self; + + if !msrv.meets(msrvs::STD_INTEGRAL_CONSTANTS) || in_external_macro(cx.sess(), expr.span) { + return; + } + let ExprKind::Path(qpath) = expr.kind else { + return; + }; + + // `std::::` check + let (span, sugg, is_method, use_stmts) = if let QPath::Resolved(_, path) = qpath + && let Some(def_id) = path.res.opt_def_id() + && let Some(name) = path.segments.iter().last().map(|segment| segment.ident.name) + && let Some(module_name) = is_path_in_integral_module(cx, def_id) + { + ( + expr.span, + format!("{module_name}::{name}"), + false, + if path.segments.get(0).is_some_and(|segment| segment.ident.name == module_name) { + use_stmts.get(&module_name) + } else { + None + } + ) + // `::xxx_value` check + } else if let QPath::TypeRelative(ty, _) = qpath + && let TyKind::Path(ty_qpath) = ty.kind + && let Res::PrimTy(PrimTy::Int(_) | PrimTy::Uint(_)) = cx.qpath_res(&ty_qpath, ty.hir_id) + && let last_segment = last_path_segment(&qpath) + && let name = last_segment.ident.name.as_str() + && (name == "max_value" || name == "min_value") + // Also remove the `()` + && let Some(par_expr) = get_parent_expr(cx, expr) + && let ExprKind::Call(_, _) = par_expr.kind + { + ( + qpath.last_segment_span().with_hi(par_expr.span.hi()), + name[..=2].to_ascii_uppercase(), + true, + None, + ) + } else { + return; + }; + + if !is_from_proc_macro(cx, expr) { + let msg = if is_method { + "usage of a legacy numeric method" + } else { + "usage of a legacy numeric constant" + }; + + span_lint_and_then(cx, LEGACY_NUMERIC_CONSTANTS, span, msg, |diag| { + let app = if use_stmts.is_none() { + Applicability::MachineApplicable + } else { + Applicability::MaybeIncorrect + }; + diag.span_suggestion(span, "use the associated constant instead", sugg, app); + if let Some(use_stmts) = use_stmts { + diag.span_note( + use_stmts.iter().chain(glob_use_stmts).copied().collect_vec(), + "you may need to remove one of the following `use` statements", + ); + } + }); + } + } +} + +fn is_path_in_integral_module(cx: &LateContext<'_>, def_id: DefId) -> Option { + let path = cx.get_def_path(def_id); + if let [ + sym::core | sym::std, + module @ (sym::u8 + | sym::i8 + | sym::u16 + | sym::i16 + | sym::u32 + | sym::i32 + | sym::u64 + | sym::i64 + | sym::u128 + | sym::i128 + | sym::usize + | sym::isize + | sym::f32 + | sym::f64), + .., + ] = &*cx.get_def_path(def_id) + // So `use` statements like `std::f32` also work + && path.len() <= 3 + { + return Some(*module); + } + + None +} diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index d65005aa59a7..fc71d916e7fe 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -173,7 +173,7 @@ mod large_futures; mod large_include_file; mod large_stack_arrays; mod large_stack_frames; -mod legacy_integral_constants; +mod legacy_numeric_constants; mod len_zero; mod let_if_seq; mod let_underscore; diff --git a/tests/compile-test.rs b/tests/compile-test.rs index 385e25ce6b8f..8dcc88a3e306 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -371,6 +371,7 @@ const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[ "eprint_with_newline.rs", "explicit_counter_loop.rs", "iter_skip_next_unfixable.rs", + "legacy_numeric_constants.rs", "let_and_return.rs", "literals.rs", "map_flatten.rs", diff --git a/tests/ui/checked_conversions.fixed b/tests/ui/checked_conversions.fixed index e9aca5b3a386..0d9c11f568a6 100644 --- a/tests/ui/checked_conversions.fixed +++ b/tests/ui/checked_conversions.fixed @@ -2,7 +2,7 @@ #![allow( clippy::cast_lossless, - clippy::legacy_integral_constants, + clippy::legacy_numeric_constants, unused, // Int::max_value will be deprecated in the future deprecated, diff --git a/tests/ui/checked_conversions.rs b/tests/ui/checked_conversions.rs index 645391e52acc..7cd35f2c6936 100644 --- a/tests/ui/checked_conversions.rs +++ b/tests/ui/checked_conversions.rs @@ -2,7 +2,7 @@ #![allow( clippy::cast_lossless, - clippy::legacy_integral_constants, + clippy::legacy_numeric_constants, unused, // Int::max_value will be deprecated in the future deprecated, diff --git a/tests/ui/legacy_integral_constants.fixed b/tests/ui/legacy_integral_constants.fixed deleted file mode 100644 index c1df2f8a8e59..000000000000 --- a/tests/ui/legacy_integral_constants.fixed +++ /dev/null @@ -1,33 +0,0 @@ -//@run-rustfix -//@aux-build:proc_macros.rs -#![allow(clippy::no_effect, deprecated, unused)] -#![warn(clippy::legacy_integral_constants)] - -#[macro_use] -extern crate proc_macros; - -fn main() { - f32::EPSILON; - u8::MIN; - usize::MIN; - u32::MAX; - use std::u32::MAX; - u32::MAX; - u32::MAX; - u8::MAX; - u8::MIN; - ::std::primitive::u8::MIN; - ::std::u8::MIN; - ::std::primitive::u8::MIN; - std::primitive::u32::MAX; - use std::f64; - std::primitive::f64::MAX; - // Don't lint - f32::EPSILON; - u8::MIN; - external! { - ::std::primitive::u8::MIN; - ::std::u8::MIN; - ::std::primitive::u8::min_value(); - } -} diff --git a/tests/ui/legacy_integral_constants.stderr b/tests/ui/legacy_integral_constants.stderr deleted file mode 100644 index 62e69b0d1985..000000000000 --- a/tests/ui/legacy_integral_constants.stderr +++ /dev/null @@ -1,72 +0,0 @@ -error: usage of a legacy integral constant - --> $DIR/legacy_integral_constants.rs:10:5 - | -LL | std::f32::EPSILON; - | ^^^^^^^^^^^^^^^^^ help: try: `f32::EPSILON` - | - = note: `-D clippy::legacy-integral-constants` implied by `-D warnings` - -error: usage of a legacy integral constant - --> $DIR/legacy_integral_constants.rs:11:5 - | -LL | std::u8::MIN; - | ^^^^^^^^^^^^ help: try: `u8::MIN` - -error: usage of a legacy integral constant - --> $DIR/legacy_integral_constants.rs:12:5 - | -LL | std::usize::MIN; - | ^^^^^^^^^^^^^^^ help: try: `usize::MIN` - -error: usage of a legacy integral constant - --> $DIR/legacy_integral_constants.rs:13:5 - | -LL | std::u32::MAX; - | ^^^^^^^^^^^^^ help: try: `u32::MAX` - -error: usage of a legacy integral constant - --> $DIR/legacy_integral_constants.rs:15:5 - | -LL | MAX; - | ^^^ help: try: `u32::MAX` - -error: usage of a legacy integral constant method - --> $DIR/legacy_integral_constants.rs:16:10 - | -LL | u32::max_value(); - | ^^^^^^^^^^^ help: try: `MAX` - -error: usage of a legacy integral constant method - --> $DIR/legacy_integral_constants.rs:17:9 - | -LL | u8::max_value(); - | ^^^^^^^^^^^ help: try: `MAX` - -error: usage of a legacy integral constant method - --> $DIR/legacy_integral_constants.rs:18:9 - | -LL | u8::min_value(); - | ^^^^^^^^^^^ help: try: `MIN` - -error: usage of a legacy integral constant method - --> $DIR/legacy_integral_constants.rs:21:27 - | -LL | ::std::primitive::u8::min_value(); - | ^^^^^^^^^^^ help: try: `MIN` - -error: usage of a legacy integral constant method - --> $DIR/legacy_integral_constants.rs:22:26 - | -LL | std::primitive::u32::max_value(); - | ^^^^^^^^^^^ help: try: `MAX` - -error: usage of a legacy integral constant - --> $DIR/legacy_integral_constants.rs:24:5 - | -LL | f64::MAX; - | ^^^^^^^^ help: try: `std::primitive::f64::MAX` - | - = note: if you remove the `use` statement that introduces `f64`, using the above is unnecessary - -error: aborting due to 11 previous errors - diff --git a/tests/ui/legacy_integral_constants.rs b/tests/ui/legacy_numeric_constants.rs similarity index 59% rename from tests/ui/legacy_integral_constants.rs rename to tests/ui/legacy_numeric_constants.rs index 3067586b8f5b..cd22fbbcdc32 100644 --- a/tests/ui/legacy_integral_constants.rs +++ b/tests/ui/legacy_numeric_constants.rs @@ -1,18 +1,25 @@ -//@run-rustfix //@aux-build:proc_macros.rs #![allow(clippy::no_effect, deprecated, unused)] -#![warn(clippy::legacy_integral_constants)] +#![warn(clippy::legacy_numeric_constants)] #[macro_use] extern crate proc_macros; +use std::u128 as _; +pub mod a { + pub use std::u128; +} + fn main() { std::f32::EPSILON; std::u8::MIN; std::usize::MIN; std::u32::MAX; + core::u32::MAX; + use std::u32; use std::u32::MAX; MAX; + u32::MAX; u32::max_value(); u8::max_value(); u8::min_value(); @@ -22,12 +29,28 @@ fn main() { std::primitive::u32::max_value(); use std::f64; f64::MAX; + self::a::u128::MAX; + u128::MAX; // Don't lint f32::EPSILON; u8::MIN; + std::f32::consts::E; + use std::f32; + f64::consts::E; external! { ::std::primitive::u8::MIN; ::std::u8::MIN; ::std::primitive::u8::min_value(); } } + +#[clippy::msrv = "1.42.0"] +fn msrv_too_low() { + // FIXME: Why does this lint?? + std::u32::MAX; +} + +#[clippy::msrv = "1.43.0"] +fn msrv_juust_right() { + std::u32::MAX; +} diff --git a/tests/ui/legacy_numeric_constants.stderr b/tests/ui/legacy_numeric_constants.stderr new file mode 100644 index 000000000000..7e9fccbcfc23 --- /dev/null +++ b/tests/ui/legacy_numeric_constants.stderr @@ -0,0 +1,124 @@ +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:14:5 + | +LL | std::f32::EPSILON; + | ^^^^^^^^^^^^^^^^^ help: use the associated constant instead: `f32::EPSILON` + | + = note: `-D clippy::legacy-numeric-constants` implied by `-D warnings` + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:15:5 + | +LL | std::u8::MIN; + | ^^^^^^^^^^^^ help: use the associated constant instead: `u8::MIN` + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:16:5 + | +LL | std::usize::MIN; + | ^^^^^^^^^^^^^^^ help: use the associated constant instead: `usize::MIN` + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:17:5 + | +LL | std::u32::MAX; + | ^^^^^^^^^^^^^ help: use the associated constant instead: `u32::MAX` + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:18:5 + | +LL | core::u32::MAX; + | ^^^^^^^^^^^^^^ help: use the associated constant instead: `u32::MAX` + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:21:5 + | +LL | MAX; + | ^^^ help: use the associated constant instead: `u32::MAX` + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:22:5 + | +LL | u32::MAX; + | ^^^^^^^^ help: use the associated constant instead: `u32::MAX` + | +note: you may need to remove one of the following `use` statements + --> $DIR/legacy_numeric_constants.rs:20:5 + | +LL | use std::u32::MAX; + | ^^^^^^^^^^^^^^^^^^ + +error: usage of a legacy numeric method + --> $DIR/legacy_numeric_constants.rs:23:10 + | +LL | u32::max_value(); + | ^^^^^^^^^^^ help: use the associated constant instead: `MAX` + +error: usage of a legacy numeric method + --> $DIR/legacy_numeric_constants.rs:24:9 + | +LL | u8::max_value(); + | ^^^^^^^^^^^ help: use the associated constant instead: `MAX` + +error: usage of a legacy numeric method + --> $DIR/legacy_numeric_constants.rs:25:9 + | +LL | u8::min_value(); + | ^^^^^^^^^^^ help: use the associated constant instead: `MIN` + +error: usage of a legacy numeric method + --> $DIR/legacy_numeric_constants.rs:28:27 + | +LL | ::std::primitive::u8::min_value(); + | ^^^^^^^^^^^ help: use the associated constant instead: `MIN` + +error: usage of a legacy numeric method + --> $DIR/legacy_numeric_constants.rs:29:26 + | +LL | std::primitive::u32::max_value(); + | ^^^^^^^^^^^ help: use the associated constant instead: `MAX` + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:31:5 + | +LL | f64::MAX; + | ^^^^^^^^ help: use the associated constant instead: `f64::MAX` + | +note: you may need to remove one of the following `use` statements + --> $DIR/legacy_numeric_constants.rs:30:5 + | +LL | use std::f64; + | ^^^^^^^^^^^^^ + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:32:5 + | +LL | self::a::u128::MAX; + | ^^^^^^^^^^^^^^^^^^ help: use the associated constant instead: `u128::MAX` + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:35:5 + | +LL | f32::EPSILON; + | ^^^^^^^^^^^^ help: use the associated constant instead: `f32::EPSILON` + | +note: you may need to remove one of the following `use` statements + --> $DIR/legacy_numeric_constants.rs:38:5 + | +LL | use std::f32; + | ^^^^^^^^^^^^^ + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:50:5 + | +LL | std::u32::MAX; + | ^^^^^^^^^^^^^ help: use the associated constant instead: `u32::MAX` + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:55:5 + | +LL | std::u32::MAX; + | ^^^^^^^^^^^^^ help: use the associated constant instead: `u32::MAX` + +error: aborting due to 17 previous errors + diff --git a/tests/ui/manual_saturating_arithmetic.fixed b/tests/ui/manual_saturating_arithmetic.fixed index ca1b89e65c8f..6f34502d38ba 100644 --- a/tests/ui/manual_saturating_arithmetic.fixed +++ b/tests/ui/manual_saturating_arithmetic.fixed @@ -1,6 +1,6 @@ //@run-rustfix -#![allow(clippy::legacy_integral_constants, unused_imports)] +#![allow(clippy::legacy_numeric_constants, unused_imports)] use std::{i128, i32, u128, u32}; diff --git a/tests/ui/manual_saturating_arithmetic.rs b/tests/ui/manual_saturating_arithmetic.rs index 8e7cd8d75f01..55357e510c90 100644 --- a/tests/ui/manual_saturating_arithmetic.rs +++ b/tests/ui/manual_saturating_arithmetic.rs @@ -1,6 +1,6 @@ //@run-rustfix -#![allow(clippy::legacy_integral_constants, unused_imports)] +#![allow(clippy::legacy_numeric_constants, unused_imports)] use std::{i128, i32, u128, u32}; diff --git a/tests/ui/suspicious_arithmetic_impl.rs b/tests/ui/suspicious_arithmetic_impl.rs index 07cc023d608b..8f70e4ec6699 100644 --- a/tests/ui/suspicious_arithmetic_impl.rs +++ b/tests/ui/suspicious_arithmetic_impl.rs @@ -1,4 +1,4 @@ -#![allow(clippy::legacy_integral_constants)] +#![allow(clippy::legacy_numeric_constants)] #![warn(clippy::suspicious_arithmetic_impl)] use std::ops::{ Add, AddAssign, BitAnd, BitOr, BitOrAssign, BitXor, Div, DivAssign, Mul, MulAssign, Rem, Shl, Shr, Sub, From d516d56d19d768307e5d73c70063e9fad51bb658 Mon Sep 17 00:00:00 2001 From: Catherine <114838443+Centri3@users.noreply.github.com> Date: Sat, 24 Jun 2023 08:49:22 -0500 Subject: [PATCH 3/4] Split tests into two files --- tests/compile-test.rs | 1 - tests/ui/legacy_numeric_constants.fixed | 52 +++++++++++++++ tests/ui/legacy_numeric_constants.rs | 10 +-- tests/ui/legacy_numeric_constants.stderr | 64 ++++--------------- .../legacy_numeric_constants_non_rustfix.rs | 21 ++++++ ...egacy_numeric_constants_non_rustfix.stderr | 27 ++++++++ 6 files changed, 117 insertions(+), 58 deletions(-) create mode 100644 tests/ui/legacy_numeric_constants.fixed create mode 100644 tests/ui/legacy_numeric_constants_non_rustfix.rs create mode 100644 tests/ui/legacy_numeric_constants_non_rustfix.stderr diff --git a/tests/compile-test.rs b/tests/compile-test.rs index 8dcc88a3e306..385e25ce6b8f 100644 --- a/tests/compile-test.rs +++ b/tests/compile-test.rs @@ -371,7 +371,6 @@ const RUSTFIX_COVERAGE_KNOWN_EXCEPTIONS: &[&str] = &[ "eprint_with_newline.rs", "explicit_counter_loop.rs", "iter_skip_next_unfixable.rs", - "legacy_numeric_constants.rs", "let_and_return.rs", "literals.rs", "map_flatten.rs", diff --git a/tests/ui/legacy_numeric_constants.fixed b/tests/ui/legacy_numeric_constants.fixed new file mode 100644 index 000000000000..f543e64a793c --- /dev/null +++ b/tests/ui/legacy_numeric_constants.fixed @@ -0,0 +1,52 @@ +//@run-rustfix +//@aux-build:proc_macros.rs:proc-macro +#![allow(clippy::no_effect, deprecated, unused)] +#![warn(clippy::legacy_numeric_constants)] + +#[macro_use] +extern crate proc_macros; + +use std::u128 as _; +pub mod a { + pub use std::u128; +} + +fn main() { + f32::EPSILON; + u8::MIN; + usize::MIN; + u32::MAX; + u32::MAX; + use std::u32::MAX; + u32::MAX; + u32::MAX; + u8::MAX; + u8::MIN; + ::std::primitive::u8::MIN; + ::std::u8::MIN; + ::std::primitive::u8::MIN; + std::primitive::u32::MAX; + u128::MAX; + // Don't lint + use std::f64; + f32::EPSILON; + u8::MIN; + std::f32::consts::E; + f64::consts::E; + external! { + ::std::primitive::u8::MIN; + ::std::u8::MIN; + ::std::primitive::u8::min_value(); + } +} + +#[clippy::msrv = "1.42.0"] +fn msrv_too_low() { + // FIXME: Why does this lint?? + u32::MAX; +} + +#[clippy::msrv = "1.43.0"] +fn msrv_juust_right() { + u32::MAX; +} diff --git a/tests/ui/legacy_numeric_constants.rs b/tests/ui/legacy_numeric_constants.rs index cd22fbbcdc32..afaa3700f65d 100644 --- a/tests/ui/legacy_numeric_constants.rs +++ b/tests/ui/legacy_numeric_constants.rs @@ -1,4 +1,5 @@ -//@aux-build:proc_macros.rs +//@run-rustfix +//@aux-build:proc_macros.rs:proc-macro #![allow(clippy::no_effect, deprecated, unused)] #![warn(clippy::legacy_numeric_constants)] @@ -16,10 +17,8 @@ fn main() { std::usize::MIN; std::u32::MAX; core::u32::MAX; - use std::u32; use std::u32::MAX; MAX; - u32::MAX; u32::max_value(); u8::max_value(); u8::min_value(); @@ -27,15 +26,12 @@ fn main() { ::std::u8::MIN; ::std::primitive::u8::min_value(); std::primitive::u32::max_value(); - use std::f64; - f64::MAX; self::a::u128::MAX; - u128::MAX; // Don't lint + use std::f64; f32::EPSILON; u8::MIN; std::f32::consts::E; - use std::f32; f64::consts::E; external! { ::std::primitive::u8::MIN; diff --git a/tests/ui/legacy_numeric_constants.stderr b/tests/ui/legacy_numeric_constants.stderr index 7e9fccbcfc23..0daf9a53c3d0 100644 --- a/tests/ui/legacy_numeric_constants.stderr +++ b/tests/ui/legacy_numeric_constants.stderr @@ -1,5 +1,5 @@ error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:14:5 + --> $DIR/legacy_numeric_constants.rs:15:5 | LL | std::f32::EPSILON; | ^^^^^^^^^^^^^^^^^ help: use the associated constant instead: `f32::EPSILON` @@ -7,25 +7,25 @@ LL | std::f32::EPSILON; = note: `-D clippy::legacy-numeric-constants` implied by `-D warnings` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:15:5 + --> $DIR/legacy_numeric_constants.rs:16:5 | LL | std::u8::MIN; | ^^^^^^^^^^^^ help: use the associated constant instead: `u8::MIN` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:16:5 + --> $DIR/legacy_numeric_constants.rs:17:5 | LL | std::usize::MIN; | ^^^^^^^^^^^^^^^ help: use the associated constant instead: `usize::MIN` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:17:5 + --> $DIR/legacy_numeric_constants.rs:18:5 | LL | std::u32::MAX; | ^^^^^^^^^^^^^ help: use the associated constant instead: `u32::MAX` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:18:5 + --> $DIR/legacy_numeric_constants.rs:19:5 | LL | core::u32::MAX; | ^^^^^^^^^^^^^^ help: use the associated constant instead: `u32::MAX` @@ -36,89 +36,53 @@ error: usage of a legacy numeric constant LL | MAX; | ^^^ help: use the associated constant instead: `u32::MAX` -error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:22:5 - | -LL | u32::MAX; - | ^^^^^^^^ help: use the associated constant instead: `u32::MAX` - | -note: you may need to remove one of the following `use` statements - --> $DIR/legacy_numeric_constants.rs:20:5 - | -LL | use std::u32::MAX; - | ^^^^^^^^^^^^^^^^^^ - error: usage of a legacy numeric method - --> $DIR/legacy_numeric_constants.rs:23:10 + --> $DIR/legacy_numeric_constants.rs:22:10 | LL | u32::max_value(); | ^^^^^^^^^^^ help: use the associated constant instead: `MAX` error: usage of a legacy numeric method - --> $DIR/legacy_numeric_constants.rs:24:9 + --> $DIR/legacy_numeric_constants.rs:23:9 | LL | u8::max_value(); | ^^^^^^^^^^^ help: use the associated constant instead: `MAX` error: usage of a legacy numeric method - --> $DIR/legacy_numeric_constants.rs:25:9 + --> $DIR/legacy_numeric_constants.rs:24:9 | LL | u8::min_value(); | ^^^^^^^^^^^ help: use the associated constant instead: `MIN` error: usage of a legacy numeric method - --> $DIR/legacy_numeric_constants.rs:28:27 + --> $DIR/legacy_numeric_constants.rs:27:27 | LL | ::std::primitive::u8::min_value(); | ^^^^^^^^^^^ help: use the associated constant instead: `MIN` error: usage of a legacy numeric method - --> $DIR/legacy_numeric_constants.rs:29:26 + --> $DIR/legacy_numeric_constants.rs:28:26 | LL | std::primitive::u32::max_value(); | ^^^^^^^^^^^ help: use the associated constant instead: `MAX` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:31:5 - | -LL | f64::MAX; - | ^^^^^^^^ help: use the associated constant instead: `f64::MAX` - | -note: you may need to remove one of the following `use` statements - --> $DIR/legacy_numeric_constants.rs:30:5 - | -LL | use std::f64; - | ^^^^^^^^^^^^^ - -error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:32:5 + --> $DIR/legacy_numeric_constants.rs:29:5 | LL | self::a::u128::MAX; | ^^^^^^^^^^^^^^^^^^ help: use the associated constant instead: `u128::MAX` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:35:5 - | -LL | f32::EPSILON; - | ^^^^^^^^^^^^ help: use the associated constant instead: `f32::EPSILON` - | -note: you may need to remove one of the following `use` statements - --> $DIR/legacy_numeric_constants.rs:38:5 - | -LL | use std::f32; - | ^^^^^^^^^^^^^ - -error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:50:5 + --> $DIR/legacy_numeric_constants.rs:46:5 | LL | std::u32::MAX; | ^^^^^^^^^^^^^ help: use the associated constant instead: `u32::MAX` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:55:5 + --> $DIR/legacy_numeric_constants.rs:51:5 | LL | std::u32::MAX; | ^^^^^^^^^^^^^ help: use the associated constant instead: `u32::MAX` -error: aborting due to 17 previous errors +error: aborting due to 14 previous errors diff --git a/tests/ui/legacy_numeric_constants_non_rustfix.rs b/tests/ui/legacy_numeric_constants_non_rustfix.rs new file mode 100644 index 000000000000..439a10a61b6e --- /dev/null +++ b/tests/ui/legacy_numeric_constants_non_rustfix.rs @@ -0,0 +1,21 @@ +//@aux-build:proc_macros.rs:proc-macro +#![allow(clippy::no_effect, deprecated, unused)] +#![warn(clippy::legacy_numeric_constants)] + +#[macro_use] +extern crate proc_macros; + +use std::u128 as _; + +fn main() { + use std::u32; + u32::MAX; + use std::f64; + f64::MAX; + u128::MAX; + // Don't lint + u8::MIN; + std::f32::consts::E; + use std::f32; + f64::consts::E; +} diff --git a/tests/ui/legacy_numeric_constants_non_rustfix.stderr b/tests/ui/legacy_numeric_constants_non_rustfix.stderr new file mode 100644 index 000000000000..85468e498ca5 --- /dev/null +++ b/tests/ui/legacy_numeric_constants_non_rustfix.stderr @@ -0,0 +1,27 @@ +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants_non_rustfix.rs:12:5 + | +LL | u32::MAX; + | ^^^^^^^^ help: use the associated constant instead: `u32::MAX` + | +note: you may need to remove one of the following `use` statements + --> $DIR/legacy_numeric_constants_non_rustfix.rs:11:5 + | +LL | use std::u32; + | ^^^^^^^^^^^^^ + = note: `-D clippy::legacy-numeric-constants` implied by `-D warnings` + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants_non_rustfix.rs:14:5 + | +LL | f64::MAX; + | ^^^^^^^^ help: use the associated constant instead: `f64::MAX` + | +note: you may need to remove one of the following `use` statements + --> $DIR/legacy_numeric_constants_non_rustfix.rs:13:5 + | +LL | use std::f64; + | ^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + From 1ad0d75a6e29343870eef944b42ee2ba145cae42 Mon Sep 17 00:00:00 2001 From: Catherine Flores Date: Tue, 8 Aug 2023 17:00:57 -0500 Subject: [PATCH 4/4] Refine stderr --- book/src/lint_configuration.md | 1 + clippy_lints/src/legacy_numeric_constants.rs | 204 +++++++++--------- clippy_lints/src/lib.rs | 2 +- clippy_lints/src/utils/conf.rs | 2 +- clippy_utils/src/check_proc_macro.rs | 12 +- clippy_utils/src/msrvs.rs | 2 +- tests/ui/legacy_numeric_constants.fixed | 3 + tests/ui/legacy_numeric_constants.rs | 65 +++++- tests/ui/legacy_numeric_constants.stderr | 117 ++++++++-- .../legacy_numeric_constants_non_rustfix.rs | 21 -- ...egacy_numeric_constants_non_rustfix.stderr | 27 --- 11 files changed, 276 insertions(+), 180 deletions(-) delete mode 100644 tests/ui/legacy_numeric_constants_non_rustfix.rs delete mode 100644 tests/ui/legacy_numeric_constants_non_rustfix.stderr diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index caaad6d11736..46311d68a882 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -151,6 +151,7 @@ The minimum rust version that the project supports * [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds) * [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions) * [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold) +* [`legacy_numeric_constants`](https://rust-lang.github.io/rust-clippy/master/index.html#legacy_numeric_constants) ## `cognitive-complexity-threshold` diff --git a/clippy_lints/src/legacy_numeric_constants.rs b/clippy_lints/src/legacy_numeric_constants.rs index b5999a996d5e..baae31c82ffc 100644 --- a/clippy_lints/src/legacy_numeric_constants.rs +++ b/clippy_lints/src/legacy_numeric_constants.rs @@ -1,22 +1,17 @@ -use clippy_utils::{ - diagnostics::span_lint_and_then, - get_parent_expr, is_from_proc_macro, last_path_segment, - msrvs::{self, Msrv}, -}; -use itertools::Itertools; -use rustc_data_structures::fx::FxHashMap; +use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then}; +use clippy_utils::msrvs::{Msrv, NUMERIC_ASSOCIATED_CONSTANTS}; +use clippy_utils::source::snippet_opt; +use clippy_utils::{get_parent_expr, is_from_proc_macro, last_path_segment, std_or_core}; use rustc_errors::Applicability; -use rustc_hir::{ - def::Res, - def_id::DefId, - intravisit::{walk_expr, Visitor}, - Item, UseKind, -}; -use rustc_hir::{Expr, ExprKind, ItemKind, PrimTy, QPath, TyKind}; +use rustc_hir::def::{DefKind, Res}; +use rustc_hir::intravisit::{walk_expr, Visitor}; +use rustc_hir::{Expr, ExprKind, Item, ItemKind, PrimTy, QPath, TyKind, UseKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::{hir::nested_filter::OnlyBodies, lint::in_external_macro}; +use rustc_middle::hir::nested_filter::OnlyBodies; +use rustc_middle::lint::in_external_macro; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::{sym, Span, Symbol}; +use rustc_span::symbol::kw; +use rustc_span::{sym, Symbol}; declare_clippy_lint! { /// ### What it does @@ -25,7 +20,7 @@ declare_clippy_lint! { /// /// ### Why is this bad? /// All of these have been superceded by the associated constants on their respective types, - /// such as `i128::MAX`. These legacy constants may be deprecated in a future version of rust. + /// such as `i128::MAX`. These legacy items may be deprecated in a future version of rust. /// /// ### Example /// ```rust @@ -42,18 +37,12 @@ declare_clippy_lint! { } pub struct LegacyNumericConstants { msrv: Msrv, - use_stmts: FxHashMap>, - glob_use_stmts: Vec, } impl LegacyNumericConstants { #[must_use] pub fn new(msrv: Msrv) -> Self { - Self { - msrv, - use_stmts: FxHashMap::default(), - glob_use_stmts: vec![], - } + Self { msrv } } } @@ -61,45 +50,51 @@ impl_lint_pass!(LegacyNumericConstants => [LEGACY_NUMERIC_CONSTANTS]); impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { - let Self { - msrv: _, - use_stmts, - glob_use_stmts, - } = self; - - if !item.span.is_dummy() && let ItemKind::Use(path, kind) = item.kind { - match kind { - UseKind::Single => { - for res in &path.res { - if let Some(def_id) = res.opt_def_id() - && let Some(module_name) = is_path_in_integral_module(cx, def_id) - && let _ = use_stmts.insert(module_name, vec![]) - && let Some(use_stmts) = use_stmts.get_mut(&module_name) - { - use_stmts.push(item.span); - } + let Self { msrv } = self; + + if msrv.meets(NUMERIC_ASSOCIATED_CONSTANTS) + && !in_external_macro(cx.sess(), item.span) + && let ItemKind::Use(path, kind @ (UseKind::Single | UseKind::Glob)) = item.kind + // These modules are "TBD" deprecated, and the contents are too, so lint on the `use` + // statement directly + && let def_path = cx.get_def_path(path.res[0].def_id()) + && is_path_in_numeric_module(&def_path, true) + { + let plurality = matches!( + kind, + UseKind::Glob | UseKind::Single if matches!(path.res[0], Res::Def(DefKind::Mod, _)), + ); + + span_lint_and_then( + cx, + LEGACY_NUMERIC_CONSTANTS, + path.span, + if plurality { + "importing legacy numeric constants" + } else { + "importing a legacy numeric constant" + }, + |diag| { + if item.ident.name != kw::Underscore { + let msg = if plurality && let [.., module_name] = &*def_path { + format!("use the associated constants on `{module_name}` instead at their usage") + } else if let [.., module_name, name] = &*def_path { + format!("use the associated constant `{module_name}::{name}` instead at its usage") + } else { + return; + }; + + diag.help(msg); } }, - UseKind::Glob => glob_use_stmts.push(item.span), - UseKind::ListStem => {}, - } + ); } } fn check_crate_post(&mut self, cx: &LateContext<'tcx>) { - let Self { - msrv, - use_stmts, - glob_use_stmts, - } = self; - - let mut v = V { - cx, - msrv, - use_stmts, - glob_use_stmts, - }; - cx.tcx.hir().visit_all_item_likes_in_crate(&mut v); + let Self { msrv } = self; + + cx.tcx.hir().visit_all_item_likes_in_crate(&mut V { cx, msrv }); } extract_msrv_attr!(LateContext); @@ -108,8 +103,6 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants { struct V<'a, 'tcx> { cx: &'a LateContext<'tcx>, msrv: &'a Msrv, - use_stmts: &'a FxHashMap>, - glob_use_stmts: &'a Vec, } impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> { @@ -121,14 +114,9 @@ impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> { fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) { walk_expr(self, expr); - let Self { - cx, - msrv, - use_stmts, - glob_use_stmts, - } = *self; - - if !msrv.meets(msrvs::STD_INTEGRAL_CONSTANTS) || in_external_macro(cx.sess(), expr.span) { + let Self { cx, msrv } = *self; + + if !msrv.meets(NUMERIC_ASSOCIATED_CONSTANTS) || in_external_macro(cx.sess(), expr.span) { return; } let ExprKind::Path(qpath) = expr.kind else { @@ -136,20 +124,26 @@ impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> { }; // `std::::` check - let (span, sugg, is_method, use_stmts) = if let QPath::Resolved(_, path) = qpath + let (span, sugg, msg) = if let QPath::Resolved(None, path) = qpath && let Some(def_id) = path.res.opt_def_id() - && let Some(name) = path.segments.iter().last().map(|segment| segment.ident.name) - && let Some(module_name) = is_path_in_integral_module(cx, def_id) + && let path = cx.get_def_path(def_id) + && is_path_in_numeric_module(&path, false) + && let [.., module_name, name] = &*path + && let Some(snippet) = snippet_opt(cx, expr.span) + && let is_float_module = (*module_name == sym::f32 || *module_name == sym::f64) + // Skip linting if this usage looks identical to the associated constant, since this + // would only require removing a `use` import. We don't ignore ones from `f32` or `f64`, however. + && let identical = snippet == format!("{module_name}::{name}") + && (!identical || is_float_module) { ( expr.span, - format!("{module_name}::{name}"), - false, - if path.segments.get(0).is_some_and(|segment| segment.ident.name == module_name) { - use_stmts.get(&module_name) - } else { + if identical { None - } + } else { + Some(format!("{module_name}::{name}")) + }, + "usage of a legacy numeric constant", ) // `::xxx_value` check } else if let QPath::TypeRelative(ty, _) = qpath @@ -164,43 +158,40 @@ impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> { { ( qpath.last_segment_span().with_hi(par_expr.span.hi()), - name[..=2].to_ascii_uppercase(), - true, - None, + Some(name[..=2].to_ascii_uppercase()), + "usage of a legacy numeric method", ) } else { return; }; if !is_from_proc_macro(cx, expr) { - let msg = if is_method { - "usage of a legacy numeric method" - } else { - "usage of a legacy numeric constant" - }; - - span_lint_and_then(cx, LEGACY_NUMERIC_CONSTANTS, span, msg, |diag| { - let app = if use_stmts.is_none() { - Applicability::MachineApplicable - } else { - Applicability::MaybeIncorrect - }; - diag.span_suggestion(span, "use the associated constant instead", sugg, app); - if let Some(use_stmts) = use_stmts { - diag.span_note( - use_stmts.iter().chain(glob_use_stmts).copied().collect_vec(), - "you may need to remove one of the following `use` statements", + span_lint_hir_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.hir_id, span, msg, |diag| { + if let Some(sugg) = sugg { + diag.span_suggestion( + span, + "use the associated constant instead", + sugg, + Applicability::MaybeIncorrect, ); + } else if let Some(std_or_core) = std_or_core(cx) + && let QPath::Resolved(None, path) = qpath + { + diag.help(format!( + "remove the import that brings `{std_or_core}::{}` into scope", + // Must be `::` if `needs_import_removed` is true yet is + // being linted + path.segments[0].ident.name, + )); } }); } } } -fn is_path_in_integral_module(cx: &LateContext<'_>, def_id: DefId) -> Option { - let path = cx.get_def_path(def_id); +fn is_path_in_numeric_module(path: &[Symbol], ignore_float_modules: bool) -> bool { if let [ - sym::core | sym::std, + sym::core, module @ (sym::u8 | sym::i8 | sym::u16 @@ -216,12 +207,17 @@ fn is_path_in_integral_module(cx: &LateContext<'_>, def_id: DefId) -> Option = None), diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs index 89f8a65c5ae0..fca4ddeedf10 100644 --- a/clippy_utils/src/check_proc_macro.rs +++ b/clippy_utils/src/check_proc_macro.rs @@ -24,7 +24,7 @@ use rustc_hir::{ use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty::TyCtxt; use rustc_session::Session; -use rustc_span::symbol::Ident; +use rustc_span::symbol::{kw, Ident}; use rustc_span::{Span, Symbol}; use rustc_target::spec::abi::Abi; @@ -103,9 +103,13 @@ fn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) { let start = if ty.is_some() { Pat::Str("<") } else { - path.segments - .first() - .map_or(Pat::Str(""), |seg| Pat::Sym(seg.ident.name)) + path.segments.first().map_or(Pat::Str(""), |seg| { + if seg.ident.name == kw::PathRoot { + Pat::Str("::") + } else { + Pat::Sym(seg.ident.name) + } + }) }; let end = path.segments.last().map_or(Pat::Str(""), |seg| { if seg.args.is_some() { diff --git a/clippy_utils/src/msrvs.rs b/clippy_utils/src/msrvs.rs index 41f4e634b402..19c571a53182 100644 --- a/clippy_utils/src/msrvs.rs +++ b/clippy_utils/src/msrvs.rs @@ -33,7 +33,7 @@ msrv_aliases! { 1,47,0 { TAU, IS_ASCII_DIGIT_CONST, ARRAY_IMPL_ANY_LEN } 1,46,0 { CONST_IF_MATCH } 1,45,0 { STR_STRIP_PREFIX } - 1,43,0 { LOG2_10, LOG10_2, STD_INTEGRAL_CONSTANTS } + 1,43,0 { LOG2_10, LOG10_2, NUMERIC_ASSOCIATED_CONSTANTS } 1,42,0 { MATCHES_MACRO, SLICE_PATTERNS, PTR_SLICE_RAW_PARTS } 1,41,0 { RE_REBALANCING_COHERENCE, RESULT_MAP_OR_ELSE } 1,40,0 { MEM_TAKE, NON_EXHAUSTIVE, OPTION_AS_DEREF } diff --git a/tests/ui/legacy_numeric_constants.fixed b/tests/ui/legacy_numeric_constants.fixed index f543e64a793c..46027682a07b 100644 --- a/tests/ui/legacy_numeric_constants.fixed +++ b/tests/ui/legacy_numeric_constants.fixed @@ -2,12 +2,14 @@ //@aux-build:proc_macros.rs:proc-macro #![allow(clippy::no_effect, deprecated, unused)] #![warn(clippy::legacy_numeric_constants)] +#![feature(lint_reasons)] #[macro_use] extern crate proc_macros; use std::u128 as _; pub mod a { + #![expect(clippy::legacy_numeric_constants)] pub use std::u128; } @@ -17,6 +19,7 @@ fn main() { usize::MIN; u32::MAX; u32::MAX; + #![expect(clippy::legacy_numeric_constants)] use std::u32::MAX; u32::MAX; u32::MAX; diff --git a/tests/ui/legacy_numeric_constants.rs b/tests/ui/legacy_numeric_constants.rs index afaa3700f65d..432455e4722e 100644 --- a/tests/ui/legacy_numeric_constants.rs +++ b/tests/ui/legacy_numeric_constants.rs @@ -1,38 +1,96 @@ -//@run-rustfix //@aux-build:proc_macros.rs:proc-macro #![allow(clippy::no_effect, deprecated, unused)] #![warn(clippy::legacy_numeric_constants)] +#![feature(lint_reasons)] #[macro_use] extern crate proc_macros; use std::u128 as _; +//~^ ERROR: importing legacy numeric constants pub mod a { pub use std::u128; + //~^ ERROR: importing legacy numeric constants + //~| HELP: use the associated constants on `u128` instead at their usage +} + +macro_rules! b { + () => { + mod b { + use std::u32; + fn b() { + let x = std::u64::MAX; + } + } + }; } fn main() { std::f32::EPSILON; + //~^ ERROR: usage of a legacy numeric constant + //~| HELP: use the associated constant instead std::u8::MIN; + //~^ ERROR: usage of a legacy numeric constant + //~| HELP: use the associated constant instead std::usize::MIN; + //~^ ERROR: usage of a legacy numeric constant + //~| HELP: use the associated constant instead std::u32::MAX; + //~^ ERROR: usage of a legacy numeric constant + //~| HELP: use the associated constant instead core::u32::MAX; + //~^ ERROR: usage of a legacy numeric constant + //~| HELP: use the associated constant instead use std::u32::MAX; + //~^ ERROR: importing a legacy numeric constant + //~| HELP: use the associated constant `u32::MAX` instead at its usage + use std::u8::MIN; + //~^ ERROR: importing a legacy numeric constant + //~| HELP: use the associated constant `u8::MIN` instead at its usage MAX; + //~^ ERROR: usage of a legacy numeric constant + //~| HELP: use the associated constant instead u32::max_value(); + //~^ ERROR: usage of a legacy numeric method + //~| HELP: use the associated constant instead u8::max_value(); + //~^ ERROR: usage of a legacy numeric method + //~| HELP: use the associated constant instead u8::min_value(); - ::std::primitive::u8::MIN; + //~^ ERROR: usage of a legacy numeric method + //~| HELP: use the associated constant instead ::std::u8::MIN; + //~^ ERROR: usage of a legacy numeric constant + //~| HELP: use the associated constant instead ::std::primitive::u8::min_value(); + //~^ ERROR: usage of a legacy numeric method + //~| HELP: use the associated constant instead std::primitive::u32::max_value(); + //~^ ERROR: usage of a legacy numeric method + //~| HELP: use the associated constant instead + f64::MAX; + //~^ ERROR: usage of a legacy numeric constant + //~| HELP: remove the import that brings `std::f64` into scope self::a::u128::MAX; - // Don't lint + //~^ ERROR: usage of a legacy numeric constant + //~| HELP: use the associated constant instead + use std::u32; + //~^ ERROR: importing legacy numeric constants + //~| HELP: use the associated constants on `u32` instead at their usage + u32::MAX; use std::f64; + u128::MAX; f32::EPSILON; + f64::EPSILON; + ::std::primitive::u8::MIN; + std::f32::consts::E; + f64::consts::E; u8::MIN; std::f32::consts::E; f64::consts::E; + b!(); + //~^ ERROR: importing legacy numeric constants + //~| HELP: use the associated constants on `u32` instead at their usage external! { ::std::primitive::u8::MIN; ::std::u8::MIN; @@ -42,7 +100,6 @@ fn main() { #[clippy::msrv = "1.42.0"] fn msrv_too_low() { - // FIXME: Why does this lint?? std::u32::MAX; } diff --git a/tests/ui/legacy_numeric_constants.stderr b/tests/ui/legacy_numeric_constants.stderr index 0daf9a53c3d0..daf29adb30f2 100644 --- a/tests/ui/legacy_numeric_constants.stderr +++ b/tests/ui/legacy_numeric_constants.stderr @@ -1,88 +1,171 @@ +error: importing legacy numeric constants + --> $DIR/legacy_numeric_constants.rs:9:5 + | +LL | use std::u128 as _; + | ^^^^^^^^^ + | + = note: `-D clippy::legacy-numeric-constants` implied by `-D warnings` + +error: importing legacy numeric constants + --> $DIR/legacy_numeric_constants.rs:12:13 + | +LL | pub use std::u128; + | ^^^^^^^^^ + | + = help: use the associated constants on `u128` instead at their usage + +error: importing a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:44:9 + | +LL | use std::u32::MAX; + | ^^^^^^^^^^^^^ + | + = help: use the associated constant `u32::MAX` instead at its usage + +error: importing a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:47:9 + | +LL | use std::u8::MIN; + | ^^^^^^^^^^^^ + | + = help: use the associated constant `u8::MIN` instead at its usage + +error: importing legacy numeric constants + --> $DIR/legacy_numeric_constants.rs:77:9 + | +LL | use std::u32; + | ^^^^^^^^ + | + = help: use the associated constants on `u32` instead at their usage + +error: importing legacy numeric constants + --> $DIR/legacy_numeric_constants.rs:20:17 + | +LL | use std::u32; + | ^^^^^^^^ +... +LL | b!(); + | ---- in this macro invocation + | + = help: use the associated constants on `u32` instead at their usage + = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) + error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:15:5 + --> $DIR/legacy_numeric_constants.rs:29:5 | LL | std::f32::EPSILON; | ^^^^^^^^^^^^^^^^^ help: use the associated constant instead: `f32::EPSILON` - | - = note: `-D clippy::legacy-numeric-constants` implied by `-D warnings` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:16:5 + --> $DIR/legacy_numeric_constants.rs:32:5 | LL | std::u8::MIN; | ^^^^^^^^^^^^ help: use the associated constant instead: `u8::MIN` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:17:5 + --> $DIR/legacy_numeric_constants.rs:35:5 | LL | std::usize::MIN; | ^^^^^^^^^^^^^^^ help: use the associated constant instead: `usize::MIN` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:18:5 + --> $DIR/legacy_numeric_constants.rs:38:5 | LL | std::u32::MAX; | ^^^^^^^^^^^^^ help: use the associated constant instead: `u32::MAX` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:19:5 + --> $DIR/legacy_numeric_constants.rs:41:5 | LL | core::u32::MAX; | ^^^^^^^^^^^^^^ help: use the associated constant instead: `u32::MAX` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:21:5 + --> $DIR/legacy_numeric_constants.rs:50:5 | LL | MAX; | ^^^ help: use the associated constant instead: `u32::MAX` error: usage of a legacy numeric method - --> $DIR/legacy_numeric_constants.rs:22:10 + --> $DIR/legacy_numeric_constants.rs:53:10 | LL | u32::max_value(); | ^^^^^^^^^^^ help: use the associated constant instead: `MAX` error: usage of a legacy numeric method - --> $DIR/legacy_numeric_constants.rs:23:9 + --> $DIR/legacy_numeric_constants.rs:56:9 | LL | u8::max_value(); | ^^^^^^^^^^^ help: use the associated constant instead: `MAX` error: usage of a legacy numeric method - --> $DIR/legacy_numeric_constants.rs:24:9 + --> $DIR/legacy_numeric_constants.rs:59:9 | LL | u8::min_value(); | ^^^^^^^^^^^ help: use the associated constant instead: `MIN` +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:62:5 + | +LL | ::std::u8::MIN; + | ^^^^^^^^^^^^^^ help: use the associated constant instead: `u8::MIN` + error: usage of a legacy numeric method - --> $DIR/legacy_numeric_constants.rs:27:27 + --> $DIR/legacy_numeric_constants.rs:65:27 | LL | ::std::primitive::u8::min_value(); | ^^^^^^^^^^^ help: use the associated constant instead: `MIN` error: usage of a legacy numeric method - --> $DIR/legacy_numeric_constants.rs:28:26 + --> $DIR/legacy_numeric_constants.rs:68:26 | LL | std::primitive::u32::max_value(); | ^^^^^^^^^^^ help: use the associated constant instead: `MAX` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:29:5 + --> $DIR/legacy_numeric_constants.rs:71:5 + | +LL | f64::MAX; + | ^^^^^^^^ + | + = help: remove the import that brings `std::f64` into scope + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:74:5 | LL | self::a::u128::MAX; | ^^^^^^^^^^^^^^^^^^ help: use the associated constant instead: `u128::MAX` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:46:5 + --> $DIR/legacy_numeric_constants.rs:84:5 + | +LL | f64::EPSILON; + | ^^^^^^^^^^^^ + | + = help: remove the import that brings `std::f64` into scope + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:22:25 + | +LL | let x = std::u64::MAX; + | ^^^^^^^^^^^^^ help: use the associated constant instead: `u64::MAX` +... +LL | b!(); + | ---- in this macro invocation + | + = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: usage of a legacy numeric constant + --> $DIR/legacy_numeric_constants.rs:103:5 | LL | std::u32::MAX; | ^^^^^^^^^^^^^ help: use the associated constant instead: `u32::MAX` error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants.rs:51:5 + --> $DIR/legacy_numeric_constants.rs:108:5 | LL | std::u32::MAX; | ^^^^^^^^^^^^^ help: use the associated constant instead: `u32::MAX` -error: aborting due to 14 previous errors +error: aborting due to 24 previous errors diff --git a/tests/ui/legacy_numeric_constants_non_rustfix.rs b/tests/ui/legacy_numeric_constants_non_rustfix.rs deleted file mode 100644 index 439a10a61b6e..000000000000 --- a/tests/ui/legacy_numeric_constants_non_rustfix.rs +++ /dev/null @@ -1,21 +0,0 @@ -//@aux-build:proc_macros.rs:proc-macro -#![allow(clippy::no_effect, deprecated, unused)] -#![warn(clippy::legacy_numeric_constants)] - -#[macro_use] -extern crate proc_macros; - -use std::u128 as _; - -fn main() { - use std::u32; - u32::MAX; - use std::f64; - f64::MAX; - u128::MAX; - // Don't lint - u8::MIN; - std::f32::consts::E; - use std::f32; - f64::consts::E; -} diff --git a/tests/ui/legacy_numeric_constants_non_rustfix.stderr b/tests/ui/legacy_numeric_constants_non_rustfix.stderr deleted file mode 100644 index 85468e498ca5..000000000000 --- a/tests/ui/legacy_numeric_constants_non_rustfix.stderr +++ /dev/null @@ -1,27 +0,0 @@ -error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants_non_rustfix.rs:12:5 - | -LL | u32::MAX; - | ^^^^^^^^ help: use the associated constant instead: `u32::MAX` - | -note: you may need to remove one of the following `use` statements - --> $DIR/legacy_numeric_constants_non_rustfix.rs:11:5 - | -LL | use std::u32; - | ^^^^^^^^^^^^^ - = note: `-D clippy::legacy-numeric-constants` implied by `-D warnings` - -error: usage of a legacy numeric constant - --> $DIR/legacy_numeric_constants_non_rustfix.rs:14:5 - | -LL | f64::MAX; - | ^^^^^^^^ help: use the associated constant instead: `f64::MAX` - | -note: you may need to remove one of the following `use` statements - --> $DIR/legacy_numeric_constants_non_rustfix.rs:13:5 - | -LL | use std::f64; - | ^^^^^^^^^^^^^ - -error: aborting due to 2 previous errors -