Skip to content

Commit 9457d64

Browse files
samueltardieuComputerDruid
authored andcommitted
refactor legacy_numeric_constants to use multipart suggestion
This removes the need for using source snippets in the replacement.
1 parent 37ddd9f commit 9457d64

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

clippy_lints/src/legacy_numeric_constants.rs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use clippy_config::Conf;
22
use clippy_utils::diagnostics::span_lint_and_then;
33
use clippy_utils::is_from_proc_macro;
44
use clippy_utils::msrvs::{self, Msrv};
5+
use clippy_utils::source::SpanRangeExt;
56
use hir::def_id::DefId;
67
use rustc_errors::Applicability;
78
use rustc_hir as hir;
@@ -103,7 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
103104

104105
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
105106
// `std::<integer>::<CONST>` check
106-
let (span, sugg, msg) = if let ExprKind::Path(qpath) = &expr.kind
107+
let (sugg, msg) = if let ExprKind::Path(qpath) = &expr.kind
107108
&& let QPath::Resolved(None, path) = qpath
108109
&& let Some(def_id) = path.res.opt_def_id()
109110
&& is_numeric_const(cx, def_id)
@@ -113,8 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
113114
&& !is_numeric_const_path_canonical(path, [*mod_name, *name])
114115
{
115116
(
116-
expr.span,
117-
format!("{mod_name}::{name}"),
117+
vec![(expr.span, format!("{mod_name}::{name}"))],
118118
"usage of a legacy numeric constant",
119119
)
120120
// `<integer>::xxx_value` check
@@ -124,13 +124,24 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
124124
&& let Some(def_id) = cx.qpath_res(qpath, func.hir_id).opt_def_id()
125125
&& is_integer_method(cx, def_id)
126126
{
127-
let name = last_segment.ident.name.as_str();
128-
let mod_name = clippy_utils::source::snippet(cx, ty.span, "_");
129-
(
130-
expr.span,
131-
format!("{}::{}", mod_name, name[..=2].to_ascii_uppercase()),
132-
"usage of a legacy numeric method",
133-
)
127+
let mut sugg = vec![
128+
// Replace the function name up to the end by the constant name
129+
(
130+
last_segment.ident.span.to(expr.span.shrink_to_hi()),
131+
last_segment.ident.name.as_str()[..=2].to_ascii_uppercase(),
132+
),
133+
];
134+
let before_span = expr.span.shrink_to_lo().until(ty.span);
135+
if !before_span.is_empty() {
136+
// Remove everything before the type name
137+
sugg.push((before_span, String::new()));
138+
}
139+
// Use `::` between the type name and the constant
140+
let between_span = ty.span.shrink_to_hi().until(last_segment.ident.span);
141+
if !between_span.check_source_text(cx, |s| s == "::") {
142+
sugg.push((between_span, String::from("::")));
143+
}
144+
(sugg, "usage of a legacy numeric method")
134145
} else {
135146
return;
136147
};
@@ -139,9 +150,8 @@ impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
139150
&& self.msrv.meets(cx, msrvs::NUMERIC_ASSOCIATED_CONSTANTS)
140151
&& !is_from_proc_macro(cx, expr)
141152
{
142-
span_lint_and_then(cx, LEGACY_NUMERIC_CONSTANTS, span, msg, |diag| {
143-
diag.span_suggestion_verbose(
144-
span,
153+
span_lint_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.span, msg, |diag| {
154+
diag.multipart_suggestion_verbose(
145155
"use the associated constant instead",
146156
sugg,
147157
Applicability::MaybeIncorrect,

0 commit comments

Comments
 (0)