Skip to content

Commit e913e6c

Browse files
committed
Remove snippet_opt
1 parent 06def10 commit e913e6c

17 files changed

+434
-180
lines changed

clippy_lints/src/casts/unnecessary_cast.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::numeric_literal::NumericLiteral;
33
use clippy_utils::res::MaybeResPath;
4-
use clippy_utils::source::{SpanExt, snippet_opt};
4+
use clippy_utils::source::SpanExt;
55
use clippy_utils::visitors::{Visitable, for_each_expr_without_closures};
66
use clippy_utils::{get_parent_expr, is_hir_ty_cfg_dependant, is_ty_alias};
77
use rustc_ast::{LitFloatType, LitIntType, LitKind};
@@ -24,7 +24,10 @@ pub(super) fn check<'tcx>(
2424
cast_from: Ty<'tcx>,
2525
cast_to: Ty<'tcx>,
2626
) -> bool {
27-
let cast_str = snippet_opt(cx, cast_expr.span).unwrap_or_default();
27+
// FIXME: Delay this to where it's needed.
28+
let Some(src) = cast_expr.span.get_text(cx) else {
29+
return false;
30+
};
2831

2932
if let ty::RawPtr(..) = cast_from.kind()
3033
// check both mutability and type are the same
@@ -57,7 +60,7 @@ pub(super) fn check<'tcx>(
5760
"casting raw pointers to the same type and constness is unnecessary (`{cast_from}` -> `{cast_to}`)"
5861
),
5962
"try",
60-
cast_str.clone(),
63+
src.to_owned(),
6164
Applicability::MaybeIncorrect,
6265
);
6366
}
@@ -103,10 +106,7 @@ pub(super) fn check<'tcx>(
103106
}
104107

105108
if let Some(lit) = get_numeric_literal(cast_expr) {
106-
let literal_str = &cast_str;
107-
108109
if let LitKind::Int(n, _) = lit.node
109-
&& let Some(src) = cast_expr.span.get_text(cx)
110110
&& cast_to.is_floating_point()
111111
&& let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node)
112112
&& let from_nbits = 128 - n.get().leading_zeros()
@@ -122,20 +122,18 @@ pub(super) fn check<'tcx>(
122122

123123
match lit.node {
124124
LitKind::Int(_, LitIntType::Unsuffixed) if cast_to.is_integral() => {
125-
lint_unnecessary_cast(cx, expr, literal_str, cast_from, cast_to);
125+
lint_unnecessary_cast(cx, expr, &src, cast_from, cast_to);
126126
return false;
127127
},
128128
LitKind::Float(_, LitFloatType::Unsuffixed) if cast_to.is_floating_point() => {
129-
lint_unnecessary_cast(cx, expr, literal_str, cast_from, cast_to);
129+
lint_unnecessary_cast(cx, expr, &src, cast_from, cast_to);
130130
return false;
131131
},
132132
LitKind::Int(_, LitIntType::Signed(_) | LitIntType::Unsigned(_))
133133
| LitKind::Float(_, LitFloatType::Suffixed(_))
134134
if cast_from.kind() == cast_to.kind() =>
135135
{
136-
if let Some(src) = cast_expr.span.get_text(cx)
137-
&& let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node)
138-
{
136+
if let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit.node) {
139137
lint_unnecessary_cast(cx, expr, num_lit.integer, cast_from, cast_to);
140138
return true;
141139
}
@@ -197,9 +195,9 @@ pub(super) fn check<'tcx>(
197195
format!("casting to the same type is unnecessary (`{cast_from}` -> `{cast_to}`)"),
198196
"try",
199197
match surrounding {
200-
MaybeParenOrBlock::Paren => format!("({cast_str})"),
201-
MaybeParenOrBlock::Block => format!("{{ {cast_str} }}"),
202-
MaybeParenOrBlock::Nothing => cast_str,
198+
MaybeParenOrBlock::Paren => format!("({src})"),
199+
MaybeParenOrBlock::Block => format!("{{ {src} }}"),
200+
MaybeParenOrBlock::Nothing => src.to_owned(),
203201
},
204202
Applicability::MachineApplicable,
205203
);

clippy_lints/src/default_numeric_fallback.rs

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use clippy_utils::diagnostics::span_lint_hir_and_then;
2-
use clippy_utils::numeric_literal;
3-
use clippy_utils::source::snippet_opt;
2+
use clippy_utils::source::SpanExt;
43
use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};
54
use rustc_errors::Applicability;
65
use rustc_hir::intravisit::{Visitor, walk_expr, walk_pat, walk_stmt};
@@ -63,6 +62,20 @@ impl<'tcx> LateLintPass<'tcx> for DefaultNumericFallback {
6362
}
6463
}
6564

65+
enum SuffixKind {
66+
Int,
67+
Float,
68+
}
69+
impl SuffixKind {
70+
fn from_ty(ty: Ty<'_>) -> Option<Self> {
71+
match *ty.kind() {
72+
ty::Int(IntTy::I32) => Some(Self::Int),
73+
ty::Float(FloatTy::F64) => Some(Self::Float),
74+
_ => None,
75+
}
76+
}
77+
}
78+
6679
struct NumericFallbackVisitor<'a, 'tcx> {
6780
/// Stack manages type bound of exprs. The top element holds current expr type.
6881
ty_bounds: Vec<ExplicitTyBound>,
@@ -90,31 +103,30 @@ impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
90103
lit.node,
91104
LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed)
92105
)
106+
&& let Some(suffix_kind) = SuffixKind::from_ty(lit_ty)
107+
&& let Some(src) = lit.span.get_text(self.cx)
108+
&& let Some(&final_char) = src.as_bytes().last()
93109
{
94-
let (suffix, is_float) = match lit_ty.kind() {
95-
ty::Int(IntTy::I32) => ("i32", false),
96-
ty::Float(FloatTy::F64) => ("f64", true),
97-
_ => return,
98-
};
99110
span_lint_hir_and_then(
100111
self.cx,
101112
DEFAULT_NUMERIC_FALLBACK,
102113
emit_hir_id,
103114
lit.span,
104115
"default numeric fallback might occur",
105116
|diag| {
106-
let src = if let Some(src) = snippet_opt(self.cx, lit.span) {
107-
src
108-
} else {
109-
match lit.node {
110-
LitKind::Int(src, _) => format!("{src}"),
111-
LitKind::Float(src, _) => format!("{src}"),
112-
_ => unreachable!("Default numeric fallback never results in other types"),
113-
}
117+
let sugg = match (suffix_kind, final_char) {
118+
(SuffixKind::Int, b'_') => "i32",
119+
(SuffixKind::Int, _) => "_i32",
120+
(SuffixKind::Float, b'_') => "f64",
121+
(SuffixKind::Float, b'.') => "0_f64",
122+
(SuffixKind::Float, _) => "_f64",
114123
};
115-
116-
let sugg = numeric_literal::format(&src, Some(suffix), is_float);
117-
diag.span_suggestion(lit.span, "consider adding suffix", sugg, Applicability::MaybeIncorrect);
124+
diag.span_suggestion_verbose(
125+
lit.span.shrink_to_hi(),
126+
"add a suffix",
127+
sugg,
128+
Applicability::MaybeIncorrect,
129+
);
118130
},
119131
);
120132
}

clippy_lints/src/doc/include_in_doc_without_cfg.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
2-
use clippy_utils::source::snippet_opt;
2+
use clippy_utils::source::SpanExt;
33
use rustc_ast::{AttrArgs, AttrKind, AttrStyle, Attribute};
44
use rustc_errors::Applicability;
55
use rustc_lint::EarlyContext;
@@ -15,7 +15,7 @@ pub fn check(cx: &EarlyContext<'_>, attrs: &[Attribute]) {
1515
&& !attr.span.contains(meta.span)
1616
// Since the `include_str` is already expanded at this point, we can only take the
1717
// whole attribute snippet and then modify for our suggestion.
18-
&& let Some(snippet) = snippet_opt(cx, attr.span)
18+
&& let Some(snippet) = attr.span.get_text(cx)
1919
// We cannot remove this because a `#[doc = include_str!("...")]` attribute can occupy
2020
// several lines.
2121
&& let Some(start) = snippet.find('[')

clippy_lints/src/doc/too_long_first_doc_paragraph.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
use clippy_utils::source::SpanExt;
12
use rustc_errors::Applicability;
23
use rustc_hir::attrs::AttributeKind;
34
use rustc_hir::{Attribute, Item, ItemKind};
45
use rustc_lint::LateContext;
56

67
use clippy_utils::diagnostics::span_lint_and_then;
78
use clippy_utils::is_from_proc_macro;
8-
use clippy_utils::source::snippet_opt;
99

1010
use super::TOO_LONG_FIRST_DOC_PARAGRAPH;
1111

@@ -81,9 +81,9 @@ pub(super) fn check(
8181
if should_suggest_empty_doc
8282
&& let Some(second_span) = spans.get(1)
8383
&& let new_span = first_span.with_hi(second_span.lo()).with_lo(first_span.hi())
84-
&& let Some(snippet) = snippet_opt(cx, new_span)
84+
&& let Some(snippet) = new_span.get_text(cx)
8585
{
86-
let Some(first) = snippet_opt(cx, *first_span) else {
86+
let Some(first) = first_span.get_text(cx) else {
8787
return;
8888
};
8989
let Some(comment_form) = first.get(..3) else {

clippy_lints/src/eta_reduction.rs

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_utils::diagnostics::span_lint_hir_and_then;
22
use clippy_utils::higher::VecArgs;
33
use clippy_utils::res::{MaybeDef, MaybeResPath};
4-
use clippy_utils::source::{snippet_opt, snippet_with_applicability};
4+
use clippy_utils::source::{SpanExt, snippet_with_applicability};
55
use clippy_utils::usage::{local_used_after_expr, local_used_in};
66
use clippy_utils::{get_path_from_caller_to_method_type, is_adjusted, is_no_std_crate};
77
use rustc_abi::ExternAbi;
@@ -215,35 +215,35 @@ fn check_closure<'tcx>(cx: &LateContext<'tcx>, outer_receiver: Option<&Expr<'tcx
215215
expr.span,
216216
"redundant closure",
217217
|diag| {
218-
if let Some(mut snippet) = snippet_opt(cx, callee.span) {
219-
if callee.res_local_id().is_some_and(|l| {
220-
// FIXME: Do we really need this `local_used_in` check?
221-
// Isn't it checking something like... `callee(callee)`?
222-
// If somehow this check is needed, add some test for it,
223-
// 'cuz currently nothing changes after deleting this check.
224-
local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr)
225-
}) {
226-
match closure_kind {
227-
// Mutable closure is used after current expr; we cannot consume it.
228-
ClosureKind::FnMut => snippet = format!("&mut {snippet}"),
229-
ClosureKind::Fn if !callee_ty_raw.is_ref() => {
230-
snippet = format!("&{snippet}");
231-
},
232-
_ => (),
233-
}
234-
} else if let n_refs =
235-
callee_ty_adjustments
236-
.iter()
237-
.rev()
238-
.fold(0, |acc, adjustment| match adjustment.kind {
218+
if let Some(snippet) = callee.span.get_text(cx) {
219+
let snippet =
220+
if callee.res_local_id().is_some_and(|l| {
221+
// FIXME: Do we really need this `local_used_in` check?
222+
// Isn't it checking something like... `callee(callee)`?
223+
// If somehow this check is needed, add some test for it,
224+
// 'cuz currently nothing changes after deleting this check.
225+
local_used_in(cx, l, args) || local_used_after_expr(cx, l, expr)
226+
}) {
227+
match closure_kind {
228+
// Mutable closure is used after current expr; we cannot consume it.
229+
ClosureKind::FnMut => format!("&mut {snippet}"),
230+
ClosureKind::Fn if !callee_ty_raw.is_ref() => {
231+
format!("&{snippet}")
232+
},
233+
_ => snippet.to_owned(),
234+
}
235+
} else if let n_refs = callee_ty_adjustments.iter().rev().fold(0, |acc, adjustment| {
236+
match adjustment.kind {
239237
Adjust::Deref(Some(_)) => acc + 1,
240238
Adjust::Deref(_) if acc > 0 => acc + 1,
241239
_ => acc,
242-
})
243-
&& n_refs > 0
244-
{
245-
snippet = format!("{}{snippet}", "*".repeat(n_refs));
246-
}
240+
}
241+
}) && n_refs > 0
242+
{
243+
format!("{}{snippet}", "*".repeat(n_refs))
244+
} else {
245+
snippet.to_owned()
246+
};
247247

248248
let replace_with = match callee_ty_adjusted.kind() {
249249
ty::FnDef(def, _) => cx.tcx.def_descr(*def),

clippy_lints/src/large_include_file.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use clippy_config::Conf;
22
use clippy_utils::diagnostics::span_lint_and_then;
33
use clippy_utils::macros::root_macro_call_first_node;
4-
use clippy_utils::source::snippet_opt;
4+
use clippy_utils::source::SpanExt;
55
use rustc_ast::{AttrArgs, AttrKind, Attribute, LitKind};
66
use rustc_hir::{Expr, ExprKind};
77
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
@@ -96,7 +96,7 @@ impl EarlyLintPass for LargeIncludeFile {
9696
&& !attr.span.contains(meta.span)
9797
// Since the `include_str` is already expanded at this point, we can only take the
9898
// whole attribute snippet and then modify for our suggestion.
99-
&& let Some(snippet) = snippet_opt(cx, attr.span)
99+
&& let Some(snippet) = attr.span.get_text(cx)
100100
// We cannot remove this because a `#[doc = include_str!("...")]` attribute can
101101
// occupy several lines.
102102
&& let Some(start) = snippet.find('[')

clippy_lints/src/loops/while_let_loop.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use super::WHILE_LET_LOOP;
22
use clippy_utils::diagnostics::span_lint_and_sugg;
3-
use clippy_utils::source::{snippet, snippet_indent, snippet_opt};
3+
use clippy_utils::source::{SpanExt, snippet, snippet_indent};
44
use clippy_utils::ty::needs_ordered_drop;
55
use clippy_utils::visitors::any_temporaries_need_ordered_drop;
66
use clippy_utils::{higher, peel_blocks};
@@ -101,8 +101,8 @@ fn could_be_while_let<'tcx>(
101101
// Prevent trivial reassignments such as `let x = x;` or `let _ = …;`, but
102102
// keep them if the type has been explicitly specified.
103103
&& (!is_trivial_assignment(pat, peel_blocks(inner_expr)) || ty.is_some())
104-
&& let Some(pat_str) = snippet_opt(cx, pat.span)
105-
&& let Some(init_str) = snippet_opt(cx, peel_blocks(inner_expr).span)
104+
&& let Some(pat_str) = pat.span.get_text(cx)
105+
&& let Some(init_str) = peel_blocks(inner_expr).span.get_text(cx)
106106
{
107107
let ty_str = ty
108108
.map(|ty| format!(": {}", snippet(cx, ty.span, "_")))

clippy_lints/src/methods/iter_overeager_cloned.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
2-
use clippy_utils::source::snippet_opt;
2+
use clippy_utils::source::SpanExt;
33
use clippy_utils::ty::{implements_trait, is_copy};
44
use rustc_ast::BindingMode;
55
use rustc_errors::Applicability;
@@ -107,14 +107,18 @@ pub(super) fn check<'tcx>(
107107
span_lint_and_then(cx, lint, expr.span, msg, |diag| match op {
108108
Op::RmCloned | Op::LaterCloned => {
109109
let method_span = expr.span.with_lo(cloned_call.span.hi());
110-
if let Some(mut snip) = snippet_opt(cx, method_span) {
111-
snip.push_str(trailing_clone);
110+
if let Some(snip) = method_span.get_text(cx) {
112111
let replace_span = expr.span.with_lo(cloned_recv.span.hi());
113-
diag.span_suggestion(replace_span, "try", snip, Applicability::MachineApplicable);
112+
diag.span_suggestion(
113+
replace_span,
114+
"try",
115+
format!("{snip}{trailing_clone}"),
116+
Applicability::MachineApplicable,
117+
);
114118
}
115119
},
116120
Op::FixClosure(name, predicate_expr) => {
117-
if let Some(predicate) = snippet_opt(cx, predicate_expr.span) {
121+
if let Some(predicate) = predicate_expr.span.get_text(cx) {
118122
let new_closure = if let ExprKind::Closure(_) = predicate_expr.kind {
119123
predicate.replacen('|', "|&", 1)
120124
} else {
@@ -127,7 +131,7 @@ pub(super) fn check<'tcx>(
127131
},
128132
Op::NeedlessMove(_) => {
129133
let method_span = expr.span.with_lo(cloned_call.span.hi());
130-
if let Some(snip) = snippet_opt(cx, method_span) {
134+
if let Some(snip) = method_span.get_text(cx) {
131135
let replace_span = expr.span.with_lo(cloned_recv.span.hi());
132136
diag.span_suggestion(replace_span, "try", snip, Applicability::MaybeIncorrect);
133137
}

clippy_lints/src/misc_early/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod unneeded_field_pattern;
77
mod unneeded_wildcard_pattern;
88
mod zero_prefixed_literal;
99

10-
use clippy_utils::source::snippet_opt;
10+
use clippy_utils::source::SpanExt;
1111
use rustc_ast::ast::{Expr, ExprKind, Generics, LitFloatType, LitIntType, LitKind, Pat};
1212
use rustc_ast::token;
1313
use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
@@ -350,7 +350,7 @@ impl MiscEarlyLints {
350350
// Note that this check also covers special case that `line!()` is eagerly expanded by compiler.
351351
// See <https://github.com/rust-lang/rust-clippy/issues/4507> for a regression.
352352
// FIXME: Find a better way to detect those cases.
353-
let lit_snip = match snippet_opt(cx, span) {
353+
let lit_snip = match span.get_text(cx) {
354354
Some(snip) if snip.starts_with(|c: char| c.is_ascii_digit()) => snip,
355355
_ => return,
356356
};

clippy_lints/src/raw_strings.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_config::Conf;
22
use clippy_utils::diagnostics::span_lint_and_then;
3-
use clippy_utils::source::{SpanExt, snippet_opt};
3+
use clippy_utils::source::SpanExt;
44
use rustc_ast::ast::{Expr, ExprKind};
55
use rustc_ast::token::LitKind;
66
use rustc_errors::Applicability;
@@ -72,19 +72,14 @@ impl EarlyLintPass for RawStrings {
7272
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
7373
if let ExprKind::FormatArgs(format_args) = &expr.kind
7474
&& !format_args.span.in_external_macro(cx.sess().source_map())
75-
&& format_args.span.check_text(cx, |src| src.starts_with('r'))
76-
&& let Some(str) = snippet_opt(cx.sess(), format_args.span)
77-
&& let count_hash = str.bytes().skip(1).take_while(|b| *b == b'#').count()
78-
&& let Some(str) = str.get(count_hash + 2..str.len() - count_hash - 1)
75+
&& let Some(src) = format_args.span.get_text(cx)
76+
&& let Some(src) = src.strip_prefix('r')
77+
&& let src_trimmed = src.trim_start_matches('#')
78+
&& let Ok(hash_count) = u8::try_from(src.len() - src_trimmed.len())
79+
&& let Some(str) = src_trimmed.trim_end_matches('#').strip_prefix('"')
80+
&& let Some(str) = str.strip_suffix('"')
7981
{
80-
self.check_raw_string(
81-
cx,
82-
str,
83-
format_args.span,
84-
"r",
85-
u8::try_from(count_hash).unwrap(),
86-
"string",
87-
);
82+
self.check_raw_string(cx, str, format_args.span, "r", hash_count, "string");
8883
}
8984

9085
if let ExprKind::Lit(lit) = expr.kind

0 commit comments

Comments
 (0)