fix legacy_numeric_constants suggestion when call is wrapped in parens (#15191)
Fixes rust-lang/rust-clippy#15008 changelog: [`legacy_numeric_constants`]: fix suggestion when call is inside parentheses like `(i32::max_value())`
This commit is contained in:
commit
488f4dd04d
4 changed files with 172 additions and 38 deletions
|
|
@ -1,7 +1,8 @@
|
|||
use clippy_config::Conf;
|
||||
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::is_from_proc_macro;
|
||||
use clippy_utils::msrvs::{self, Msrv};
|
||||
use clippy_utils::{get_parent_expr, is_from_proc_macro};
|
||||
use clippy_utils::source::SpanRangeExt;
|
||||
use hir::def_id::DefId;
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir as hir;
|
||||
|
|
@ -102,39 +103,45 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
|
|||
}
|
||||
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
|
||||
let ExprKind::Path(qpath) = &expr.kind else {
|
||||
return;
|
||||
};
|
||||
|
||||
// `std::<integer>::<CONST>` check
|
||||
let (span, sugg, msg) = if let QPath::Resolved(None, path) = qpath
|
||||
let (sugg, msg) = if let ExprKind::Path(qpath) = &expr.kind
|
||||
&& let QPath::Resolved(None, path) = qpath
|
||||
&& let Some(def_id) = path.res.opt_def_id()
|
||||
&& is_numeric_const(cx, def_id)
|
||||
&& let def_path = cx.get_def_path(def_id)
|
||||
&& let [.., mod_name, name] = &*def_path
|
||||
&& let [.., mod_name, name] = &*cx.get_def_path(def_id)
|
||||
// Skip linting if this usage looks identical to the associated constant,
|
||||
// since this would only require removing a `use` import (which is already linted).
|
||||
&& !is_numeric_const_path_canonical(path, [*mod_name, *name])
|
||||
{
|
||||
(
|
||||
expr.span,
|
||||
format!("{mod_name}::{name}"),
|
||||
vec![(expr.span, format!("{mod_name}::{name}"))],
|
||||
"usage of a legacy numeric constant",
|
||||
)
|
||||
// `<integer>::xxx_value` check
|
||||
} else if let QPath::TypeRelative(_, last_segment) = qpath
|
||||
&& let Some(def_id) = cx.qpath_res(qpath, expr.hir_id).opt_def_id()
|
||||
&& let Some(par_expr) = get_parent_expr(cx, expr)
|
||||
&& let ExprKind::Call(_, []) = par_expr.kind
|
||||
} else if let ExprKind::Call(func, []) = &expr.kind
|
||||
&& let ExprKind::Path(qpath) = &func.kind
|
||||
&& let QPath::TypeRelative(ty, last_segment) = qpath
|
||||
&& let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id()
|
||||
&& is_integer_method(cx, def_id)
|
||||
{
|
||||
let name = last_segment.ident.name.as_str();
|
||||
|
||||
(
|
||||
last_segment.ident.span.with_hi(par_expr.span.hi()),
|
||||
name[..=2].to_ascii_uppercase(),
|
||||
"usage of a legacy numeric method",
|
||||
)
|
||||
let mut sugg = vec![
|
||||
// Replace the function name up to the end by the constant name
|
||||
(
|
||||
last_segment.ident.span.to(expr.span.shrink_to_hi()),
|
||||
last_segment.ident.name.as_str()[..=2].to_ascii_uppercase(),
|
||||
),
|
||||
];
|
||||
let before_span = expr.span.shrink_to_lo().until(ty.span);
|
||||
if !before_span.is_empty() {
|
||||
// Remove everything before the type name
|
||||
sugg.push((before_span, String::new()));
|
||||
}
|
||||
// Use `::` between the type name and the constant
|
||||
let between_span = ty.span.shrink_to_hi().until(last_segment.ident.span);
|
||||
if !between_span.check_source_text(cx, |s| s == "::") {
|
||||
sugg.push((between_span, String::from("::")));
|
||||
}
|
||||
(sugg, "usage of a legacy numeric method")
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
|
|
@ -143,9 +150,8 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
|
|||
&& self.msrv.meets(cx, msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
|
||||
&& !is_from_proc_macro(cx, expr)
|
||||
{
|
||||
span_lint_hir_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.hir_id, span, msg, |diag| {
|
||||
diag.span_suggestion_verbose(
|
||||
span,
|
||||
span_lint_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.span, msg, |diag| {
|
||||
diag.multipart_suggestion_verbose(
|
||||
"use the associated constant instead",
|
||||
sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
|
|
|
|||
|
|
@ -79,9 +79,31 @@ fn main() {
|
|||
f64::consts::E;
|
||||
b!();
|
||||
|
||||
std::primitive::i32::MAX;
|
||||
//~^ ERROR: usage of a legacy numeric method
|
||||
//~| HELP: use the associated constant instead
|
||||
[(0, "", i128::MAX)];
|
||||
//~^ ERROR: usage of a legacy numeric constant
|
||||
//~| HELP: use the associated constant instead
|
||||
i32::MAX;
|
||||
//~^ ERROR: usage of a legacy numeric method
|
||||
//~| HELP: use the associated constant instead
|
||||
assert_eq!(0, -i32::MAX);
|
||||
//~^ ERROR: usage of a legacy numeric method
|
||||
//~| HELP: use the associated constant instead
|
||||
i128::MAX;
|
||||
//~^ ERROR: usage of a legacy numeric constant
|
||||
//~| HELP: use the associated constant instead
|
||||
u32::MAX;
|
||||
//~^ ERROR: usage of a legacy numeric method
|
||||
//~| HELP: use the associated constant instead
|
||||
i32::MAX;
|
||||
//~^ ERROR: usage of a legacy numeric method
|
||||
//~| HELP: use the associated constant instead
|
||||
type Ω = i32;
|
||||
Ω::MAX;
|
||||
//~^ ERROR: usage of a legacy numeric method
|
||||
//~| HELP: use the associated constant instead
|
||||
}
|
||||
|
||||
#[warn(clippy::legacy_numeric_constants)]
|
||||
|
|
|
|||
|
|
@ -79,9 +79,31 @@ fn main() {
|
|||
f64::consts::E;
|
||||
b!();
|
||||
|
||||
<std::primitive::i32>::max_value();
|
||||
//~^ ERROR: usage of a legacy numeric method
|
||||
//~| HELP: use the associated constant instead
|
||||
[(0, "", std::i128::MAX)];
|
||||
//~^ ERROR: usage of a legacy numeric constant
|
||||
//~| HELP: use the associated constant instead
|
||||
(i32::max_value());
|
||||
//~^ ERROR: usage of a legacy numeric method
|
||||
//~| HELP: use the associated constant instead
|
||||
assert_eq!(0, -(i32::max_value()));
|
||||
//~^ ERROR: usage of a legacy numeric method
|
||||
//~| HELP: use the associated constant instead
|
||||
(std::i128::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
|
||||
((i32::max_value)());
|
||||
//~^ ERROR: usage of a legacy numeric method
|
||||
//~| HELP: use the associated constant instead
|
||||
type Ω = i32;
|
||||
Ω::max_value();
|
||||
//~^ ERROR: usage of a legacy numeric method
|
||||
//~| HELP: use the associated constant instead
|
||||
}
|
||||
|
||||
#[warn(clippy::legacy_numeric_constants)]
|
||||
|
|
|
|||
|
|
@ -72,10 +72,10 @@ LL | u32::MAX;
|
|||
| +++++
|
||||
|
||||
error: usage of a legacy numeric method
|
||||
--> tests/ui/legacy_numeric_constants.rs:50:10
|
||||
--> tests/ui/legacy_numeric_constants.rs:50:5
|
||||
|
|
||||
LL | i32::max_value();
|
||||
| ^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use the associated constant instead
|
||||
|
|
||||
|
|
@ -84,10 +84,10 @@ LL + i32::MAX;
|
|||
|
|
||||
|
||||
error: usage of a legacy numeric method
|
||||
--> tests/ui/legacy_numeric_constants.rs:53:9
|
||||
--> tests/ui/legacy_numeric_constants.rs:53:5
|
||||
|
|
||||
LL | u8::max_value();
|
||||
| ^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use the associated constant instead
|
||||
|
|
||||
|
|
@ -96,10 +96,10 @@ LL + u8::MAX;
|
|||
|
|
||||
|
||||
error: usage of a legacy numeric method
|
||||
--> tests/ui/legacy_numeric_constants.rs:56:9
|
||||
--> tests/ui/legacy_numeric_constants.rs:56:5
|
||||
|
|
||||
LL | u8::min_value();
|
||||
| ^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use the associated constant instead
|
||||
|
|
||||
|
|
@ -120,10 +120,10 @@ LL + u8::MIN;
|
|||
|
|
||||
|
||||
error: usage of a legacy numeric method
|
||||
--> tests/ui/legacy_numeric_constants.rs:62:27
|
||||
--> tests/ui/legacy_numeric_constants.rs:62:5
|
||||
|
|
||||
LL | ::std::primitive::u8::min_value();
|
||||
| ^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use the associated constant instead
|
||||
|
|
||||
|
|
@ -132,10 +132,10 @@ LL + ::std::primitive::u8::MIN;
|
|||
|
|
||||
|
||||
error: usage of a legacy numeric method
|
||||
--> tests/ui/legacy_numeric_constants.rs:65:26
|
||||
--> tests/ui/legacy_numeric_constants.rs:65:5
|
||||
|
|
||||
LL | std::primitive::i32::max_value();
|
||||
| ^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use the associated constant instead
|
||||
|
|
||||
|
|
@ -171,8 +171,20 @@ LL - let x = std::u64::MAX;
|
|||
LL + let x = u64::MAX;
|
||||
|
|
||||
|
||||
error: usage of a legacy numeric method
|
||||
--> tests/ui/legacy_numeric_constants.rs:82:5
|
||||
|
|
||||
LL | <std::primitive::i32>::max_value();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use the associated constant instead
|
||||
|
|
||||
LL - <std::primitive::i32>::max_value();
|
||||
LL + std::primitive::i32::MAX;
|
||||
|
|
||||
|
||||
error: usage of a legacy numeric constant
|
||||
--> tests/ui/legacy_numeric_constants.rs:82:14
|
||||
--> tests/ui/legacy_numeric_constants.rs:85:14
|
||||
|
|
||||
LL | [(0, "", std::i128::MAX)];
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
@ -183,8 +195,80 @@ LL - [(0, "", std::i128::MAX)];
|
|||
LL + [(0, "", i128::MAX)];
|
||||
|
|
||||
|
||||
error: usage of a legacy numeric method
|
||||
--> tests/ui/legacy_numeric_constants.rs:88:5
|
||||
|
|
||||
LL | (i32::max_value());
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use the associated constant instead
|
||||
|
|
||||
LL - (i32::max_value());
|
||||
LL + i32::MAX;
|
||||
|
|
||||
|
||||
error: usage of a legacy numeric method
|
||||
--> tests/ui/legacy_numeric_constants.rs:91:20
|
||||
|
|
||||
LL | assert_eq!(0, -(i32::max_value()));
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use the associated constant instead
|
||||
|
|
||||
LL - assert_eq!(0, -(i32::max_value()));
|
||||
LL + assert_eq!(0, -i32::MAX);
|
||||
|
|
||||
|
||||
error: usage of a legacy numeric constant
|
||||
--> tests/ui/legacy_numeric_constants.rs:116:5
|
||||
--> tests/ui/legacy_numeric_constants.rs:94:5
|
||||
|
|
||||
LL | (std::i128::MAX);
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use the associated constant instead
|
||||
|
|
||||
LL - (std::i128::MAX);
|
||||
LL + i128::MAX;
|
||||
|
|
||||
|
||||
error: usage of a legacy numeric method
|
||||
--> tests/ui/legacy_numeric_constants.rs:97:5
|
||||
|
|
||||
LL | (<u32>::max_value());
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use the associated constant instead
|
||||
|
|
||||
LL - (<u32>::max_value());
|
||||
LL + u32::MAX;
|
||||
|
|
||||
|
||||
error: usage of a legacy numeric method
|
||||
--> tests/ui/legacy_numeric_constants.rs:100:5
|
||||
|
|
||||
LL | ((i32::max_value)());
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use the associated constant instead
|
||||
|
|
||||
LL - ((i32::max_value)());
|
||||
LL + i32::MAX;
|
||||
|
|
||||
|
||||
error: usage of a legacy numeric method
|
||||
--> tests/ui/legacy_numeric_constants.rs:104:5
|
||||
|
|
||||
LL | Ω::max_value();
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
help: use the associated constant instead
|
||||
|
|
||||
LL - Ω::max_value();
|
||||
LL + Ω::MAX;
|
||||
|
|
||||
|
||||
error: usage of a legacy numeric constant
|
||||
--> tests/ui/legacy_numeric_constants.rs:138:5
|
||||
|
|
||||
LL | std::u32::MAX;
|
||||
| ^^^^^^^^^^^^^
|
||||
|
|
@ -195,5 +279,5 @@ LL - std::u32::MAX;
|
|||
LL + u32::MAX;
|
||||
|
|
||||
|
||||
error: aborting due to 16 previous errors
|
||||
error: aborting due to 23 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue