Auto merge of #13244 - Jarcho:get_src_display, r=Alexendoo
Start removing `snippet_opt` in favor of `get_source_text` Continuing the job of removing unnecessary allocations. changelog: none
This commit is contained in:
commit
ecfc7d906f
@ -1,6 +1,6 @@
|
|||||||
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
|
use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
|
||||||
use clippy_utils::eq_expr_value;
|
use clippy_utils::eq_expr_value;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
|
||||||
use rustc_ast::ast::LitKind;
|
use rustc_ast::ast::LitKind;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
@ -134,28 +134,30 @@ fn check_inverted_bool_in_condition(
|
|||||||
|
|
||||||
let suggestion = match (left.kind, right.kind) {
|
let suggestion = match (left.kind, right.kind) {
|
||||||
(ExprKind::Unary(UnOp::Not, left_sub), ExprKind::Unary(UnOp::Not, right_sub)) => {
|
(ExprKind::Unary(UnOp::Not, left_sub), ExprKind::Unary(UnOp::Not, right_sub)) => {
|
||||||
let Some(left) = snippet_opt(cx, left_sub.span) else {
|
let Some(left) = left_sub.span.get_source_text(cx) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(right) = snippet_opt(cx, right_sub.span) else {
|
let Some(right) = right_sub.span.get_source_text(cx) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(op) = bin_op_eq_str(op) else { return };
|
let Some(op) = bin_op_eq_str(op) else { return };
|
||||||
format!("{left} {op} {right}")
|
format!("{left} {op} {right}")
|
||||||
},
|
},
|
||||||
(ExprKind::Unary(UnOp::Not, left_sub), _) => {
|
(ExprKind::Unary(UnOp::Not, left_sub), _) => {
|
||||||
let Some(left) = snippet_opt(cx, left_sub.span) else {
|
let Some(left) = left_sub.span.get_source_text(cx) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(right) = snippet_opt(cx, right.span) else {
|
let Some(right) = right.span.get_source_text(cx) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(op) = inverted_bin_op_eq_str(op) else { return };
|
let Some(op) = inverted_bin_op_eq_str(op) else { return };
|
||||||
format!("{left} {op} {right}")
|
format!("{left} {op} {right}")
|
||||||
},
|
},
|
||||||
(_, ExprKind::Unary(UnOp::Not, right_sub)) => {
|
(_, ExprKind::Unary(UnOp::Not, right_sub)) => {
|
||||||
let Some(left) = snippet_opt(cx, left.span) else { return };
|
let Some(left) = left.span.get_source_text(cx) else {
|
||||||
let Some(right) = snippet_opt(cx, right_sub.span) else {
|
return;
|
||||||
|
};
|
||||||
|
let Some(right) = right_sub.span.get_source_text(cx) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(op) = inverted_bin_op_eq_str(op) else { return };
|
let Some(op) = inverted_bin_op_eq_str(op) else { return };
|
||||||
@ -313,8 +315,7 @@ fn recurse(&mut self, suggestion: &Bool) -> Option<()> {
|
|||||||
self.output.push_str(&str);
|
self.output.push_str(&str);
|
||||||
} else {
|
} else {
|
||||||
self.output.push('!');
|
self.output.push('!');
|
||||||
let snip = snippet_opt(self.cx, terminal.span)?;
|
self.output.push_str(&terminal.span.get_source_text(self.cx)?);
|
||||||
self.output.push_str(&snip);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
True | False | Not(_) => {
|
True | False | Not(_) => {
|
||||||
@ -345,8 +346,12 @@ fn recurse(&mut self, suggestion: &Bool) -> Option<()> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
&Term(n) => {
|
&Term(n) => {
|
||||||
let snip = snippet_opt(self.cx, self.terminals[n as usize].span.source_callsite())?;
|
self.output.push_str(
|
||||||
self.output.push_str(&snip);
|
&self.terminals[n as usize]
|
||||||
|
.span
|
||||||
|
.source_callsite()
|
||||||
|
.get_source_text(self.cx)?,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
Some(())
|
Some(())
|
||||||
@ -370,8 +375,8 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
.and_then(|op| {
|
.and_then(|op| {
|
||||||
let lhs_snippet = snippet_opt(cx, lhs.span)?;
|
let lhs_snippet = lhs.span.get_source_text(cx)?;
|
||||||
let rhs_snippet = snippet_opt(cx, rhs.span)?;
|
let rhs_snippet = rhs.span.get_source_text(cx)?;
|
||||||
|
|
||||||
if !(lhs_snippet.starts_with('(') && lhs_snippet.ends_with(')')) {
|
if !(lhs_snippet.starts_with('(') && lhs_snippet.ends_with(')')) {
|
||||||
if let (ExprKind::Cast(..), BinOpKind::Ge) = (&lhs.kind, binop.node) {
|
if let (ExprKind::Cast(..), BinOpKind::Ge) = (&lhs.kind, binop.node) {
|
||||||
@ -399,7 +404,7 @@ fn simplify_not(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<String> {
|
|||||||
let path: &str = path.ident.name.as_str();
|
let path: &str = path.ident.name.as_str();
|
||||||
a == path
|
a == path
|
||||||
})
|
})
|
||||||
.and_then(|(_, neg_method)| Some(format!("{}.{neg_method}()", snippet_opt(cx, receiver.span)?)))
|
.and_then(|(_, neg_method)| Some(format!("{}.{neg_method}()", receiver.span.get_source_text(cx)?)))
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::reference::DEREF_ADDROF;
|
use crate::reference::DEREF_ADDROF;
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use clippy_utils::ty::implements_trait;
|
use clippy_utils::ty::implements_trait;
|
||||||
use clippy_utils::{get_parent_expr, is_from_proc_macro, is_lint_allowed};
|
use clippy_utils::{get_parent_expr, is_from_proc_macro, is_lint_allowed};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
@ -73,6 +73,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &rustc_hir::Expr<'tcx>) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
&& !is_from_proc_macro(cx, e)
|
&& !is_from_proc_macro(cx, e)
|
||||||
|
&& let Some(deref_text) = deref_target.span.get_source_text(cx)
|
||||||
{
|
{
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
@ -83,7 +84,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &rustc_hir::Expr<'tcx>) {
|
|||||||
diag.span_suggestion(
|
diag.span_suggestion(
|
||||||
e.span,
|
e.span,
|
||||||
"if you would like to reborrow, try removing `&*`",
|
"if you would like to reborrow, try removing `&*`",
|
||||||
snippet_opt(cx, deref_target.span).unwrap(),
|
deref_text.as_str(),
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -98,7 +99,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &rustc_hir::Expr<'tcx>) {
|
|||||||
diag.span_suggestion(
|
diag.span_suggestion(
|
||||||
e.span,
|
e.span,
|
||||||
"if you would like to deref, try using `&**`",
|
"if you would like to deref, try using `&**`",
|
||||||
format!("&**{}", &snippet_opt(cx, deref_target.span).unwrap()),
|
format!("&**{deref_text}"),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::macros::{find_format_arg_expr, root_macro_call_first_node, FormatArgsStorage};
|
use clippy_utils::macros::{find_format_arg_expr, root_macro_call_first_node, FormatArgsStorage};
|
||||||
use clippy_utils::source::{snippet_opt, snippet_with_context};
|
use clippy_utils::source::{snippet_with_context, SpanRangeExt};
|
||||||
use clippy_utils::sugg::Sugg;
|
use clippy_utils::sugg::Sugg;
|
||||||
use rustc_ast::{FormatArgsPiece, FormatOptions, FormatTrait};
|
use rustc_ast::{FormatArgsPiece, FormatOptions, FormatTrait};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
@ -65,7 +65,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
|||||||
([], []) => span_useless_format_empty(cx, call_site, "String::new()".to_owned(), applicability),
|
([], []) => span_useless_format_empty(cx, call_site, "String::new()".to_owned(), applicability),
|
||||||
([], [_]) => {
|
([], [_]) => {
|
||||||
// Simulate macro expansion, converting {{ and }} to { and }.
|
// Simulate macro expansion, converting {{ and }} to { and }.
|
||||||
let Some(snippet) = snippet_opt(cx, format_args.span) else {
|
let Some(snippet) = format_args.span.get_source_text(cx) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let s_expand = snippet.replace("{{", "{").replace("}}", "}");
|
let s_expand = snippet.replace("{{", "{").replace("}}", "}");
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
find_format_arg_expr, format_arg_removal_span, format_placeholder_format_span, is_assert_macro, is_format_macro,
|
find_format_arg_expr, format_arg_removal_span, format_placeholder_format_span, is_assert_macro, is_format_macro,
|
||||||
is_panic, matching_root_macro_call, root_macro_call_first_node, FormatArgsStorage, FormatParamUsage, MacroCall,
|
is_panic, matching_root_macro_call, root_macro_call_first_node, FormatArgsStorage, FormatParamUsage, MacroCall,
|
||||||
};
|
};
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use clippy_utils::ty::{implements_trait, is_type_lang_item};
|
use clippy_utils::ty::{implements_trait, is_type_lang_item};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustc_ast::{
|
use rustc_ast::{
|
||||||
@ -407,7 +407,7 @@ fn check_to_string_in_format_args(&self, name: Symbol, value: &Expr<'_>) {
|
|||||||
count_needed_derefs(receiver_ty, cx.typeck_results().expr_adjustments(receiver).iter())
|
count_needed_derefs(receiver_ty, cx.typeck_results().expr_adjustments(receiver).iter())
|
||||||
&& implements_trait(cx, target, display_trait_id, &[])
|
&& implements_trait(cx, target, display_trait_id, &[])
|
||||||
&& let Some(sized_trait_id) = cx.tcx.lang_items().sized_trait()
|
&& let Some(sized_trait_id) = cx.tcx.lang_items().sized_trait()
|
||||||
&& let Some(receiver_snippet) = snippet_opt(cx, receiver.span.source_callsite())
|
&& let Some(receiver_snippet) = receiver.span.source_callsite().get_source_text(cx)
|
||||||
{
|
{
|
||||||
let needs_ref = !implements_trait(cx, receiver_ty, sized_trait_id, &[]);
|
let needs_ref = !implements_trait(cx, receiver_ty, sized_trait_id, &[]);
|
||||||
if n_needed_derefs == 0 && !needs_ref {
|
if n_needed_derefs == 0 && !needs_ref {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::macros::span_is_local;
|
use clippy_utils::macros::span_is_local;
|
||||||
use clippy_utils::path_def_id;
|
use clippy_utils::path_def_id;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::intravisit::{walk_path, Visitor};
|
use rustc_hir::intravisit::{walk_path, Visitor};
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
@ -178,8 +178,8 @@ fn convert_to_from(
|
|||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
let from = snippet_opt(cx, self_ty.span)?;
|
let from = self_ty.span.get_source_text(cx)?;
|
||||||
let into = snippet_opt(cx, target_ty.span)?;
|
let into = target_ty.span.get_source_text(cx)?;
|
||||||
|
|
||||||
let return_type = matches!(sig.decl.output, FnRetTy::Return(_))
|
let return_type = matches!(sig.decl.output, FnRetTy::Return(_))
|
||||||
.then_some(String::from("Self"))
|
.then_some(String::from("Self"))
|
||||||
@ -190,10 +190,10 @@ fn convert_to_from(
|
|||||||
(into_trait_seg.ident.span, String::from("From")),
|
(into_trait_seg.ident.span, String::from("From")),
|
||||||
// impl Into<T> for U -> impl Into<U> for U
|
// impl Into<T> for U -> impl Into<U> for U
|
||||||
// ~ ~
|
// ~ ~
|
||||||
(target_ty.span, from.clone()),
|
(target_ty.span, from.to_owned()),
|
||||||
// impl Into<T> for U -> impl Into<T> for T
|
// impl Into<T> for U -> impl Into<T> for T
|
||||||
// ~ ~
|
// ~ ~
|
||||||
(self_ty.span, into),
|
(self_ty.span, into.to_owned()),
|
||||||
// fn into(self) -> T -> fn from(self) -> T
|
// fn into(self) -> T -> fn from(self) -> T
|
||||||
// ~~~~ ~~~~
|
// ~~~~ ~~~~
|
||||||
(impl_item.ident.span, String::from("from")),
|
(impl_item.ident.span, String::from("from")),
|
||||||
@ -223,7 +223,7 @@ fn convert_to_from(
|
|||||||
}
|
}
|
||||||
|
|
||||||
for span in finder.upper {
|
for span in finder.upper {
|
||||||
suggestions.push((span, from.clone()));
|
suggestions.push((span, from.to_owned()));
|
||||||
}
|
}
|
||||||
for span in finder.lower {
|
for span in finder.lower {
|
||||||
suggestions.push((span, String::from("val")));
|
suggestions.push((span, String::from("val")));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind};
|
use rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind};
|
||||||
use rustc_ast::token;
|
use rustc_ast::token;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
@ -130,8 +130,8 @@ fn generate_recommendation(
|
|||||||
BinOpKind::Le => "<",
|
BinOpKind::Le => "<",
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
if let Some(snippet) = snippet_opt(cx, node.span) {
|
if let Some(snippet) = node.span.get_source_text(cx) {
|
||||||
if let Some(other_side_snippet) = snippet_opt(cx, other_side.span) {
|
if let Some(other_side_snippet) = other_side.span.get_source_text(cx) {
|
||||||
let rec = match side {
|
let rec = match side {
|
||||||
Side::Lhs => Some(format!("{snippet} {binop_string} {other_side_snippet}")),
|
Side::Lhs => Some(format!("{snippet} {binop_string} {other_side_snippet}")),
|
||||||
Side::Rhs => Some(format!("{other_side_snippet} {binop_string} {snippet}")),
|
Side::Rhs => Some(format!("{other_side_snippet} {binop_string} {snippet}")),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_hir_and_then;
|
use clippy_utils::diagnostics::span_lint_hir_and_then;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use clippy_utils::{fulfill_or_allowed, is_cfg_test, is_from_proc_macro};
|
use clippy_utils::{fulfill_or_allowed, is_cfg_test, is_from_proc_macro};
|
||||||
use rustc_errors::{Applicability, SuggestionStyle};
|
use rustc_errors::{Applicability, SuggestionStyle};
|
||||||
use rustc_hir::{HirId, Item, ItemKind, Mod};
|
use rustc_hir::{HirId, Item, ItemKind, Mod};
|
||||||
@ -93,11 +93,14 @@ fn check_mod(&mut self, cx: &LateContext<'_>, module: &Mod<'_>, _: HirId) {
|
|||||||
if let Some(prev) = mod_pos.checked_sub(1)
|
if let Some(prev) = mod_pos.checked_sub(1)
|
||||||
&& let prev = cx.tcx.hir().item(module.item_ids[prev])
|
&& let prev = cx.tcx.hir().item(module.item_ids[prev])
|
||||||
&& let items_span = last.span.with_lo(test_mod.span.hi())
|
&& let items_span = last.span.with_lo(test_mod.span.hi())
|
||||||
&& let Some(items) = snippet_opt(cx, items_span)
|
&& let Some(items) = items_span.get_source_text(cx)
|
||||||
{
|
{
|
||||||
diag.multipart_suggestion_with_style(
|
diag.multipart_suggestion_with_style(
|
||||||
"move the items to before the test module was defined",
|
"move the items to before the test module was defined",
|
||||||
vec![(prev.span.shrink_to_hi(), items), (items_span, String::new())],
|
vec![
|
||||||
|
(prev.span.shrink_to_hi(), items.to_owned()),
|
||||||
|
(items_span, String::new()),
|
||||||
|
],
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
SuggestionStyle::HideCodeAlways,
|
SuggestionStyle::HideCodeAlways,
|
||||||
);
|
);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
use clippy_config::Conf;
|
use clippy_config::Conf;
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::fn_has_unsatisfiable_preds;
|
use clippy_utils::fn_has_unsatisfiable_preds;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::intravisit::FnKind;
|
use rustc_hir::intravisit::FnKind;
|
||||||
use rustc_hir::{Body, FnDecl};
|
use rustc_hir::{Body, FnDecl};
|
||||||
@ -186,7 +186,7 @@ fn check_fn(
|
|||||||
// TODO: Is there a cleaner, robust way to ask this question?
|
// TODO: Is there a cleaner, robust way to ask this question?
|
||||||
// The obvious `LocalDecl::is_user_variable()` panics on "unwrapping cross-crate data",
|
// The obvious `LocalDecl::is_user_variable()` panics on "unwrapping cross-crate data",
|
||||||
// and that doesn't get us the true name in scope rather than the span text either.
|
// and that doesn't get us the true name in scope rather than the span text either.
|
||||||
if let Some(name) = snippet_opt(cx, local_span)
|
if let Some(name) = local_span.get_source_text(cx)
|
||||||
&& is_ident(&name)
|
&& is_ident(&name)
|
||||||
{
|
{
|
||||||
// If the local is an ordinary named variable,
|
// If the local is an ordinary named variable,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
|
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
|
||||||
use clippy_utils::source::{snippet_opt, snippet_with_context};
|
use clippy_utils::source::{snippet_with_context, SpanRangeExt};
|
||||||
use clippy_utils::sugg::{has_enclosing_paren, Sugg};
|
use clippy_utils::sugg::{has_enclosing_paren, Sugg};
|
||||||
use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, peel_ref_operators};
|
use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, peel_ref_operators};
|
||||||
use rustc_ast::ast::LitKind;
|
use rustc_ast::ast::LitKind;
|
||||||
@ -216,7 +216,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn span_without_enclosing_paren(cx: &LateContext<'_>, span: Span) -> Span {
|
fn span_without_enclosing_paren(cx: &LateContext<'_>, span: Span) -> Span {
|
||||||
let Some(snippet) = snippet_opt(cx, span) else {
|
let Some(snippet) = span.get_source_text(cx) else {
|
||||||
return span;
|
return span;
|
||||||
};
|
};
|
||||||
if has_enclosing_paren(snippet) {
|
if has_enclosing_paren(snippet) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use clippy_config::Conf;
|
use clippy_config::Conf;
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::numeric_literal::{NumericLiteral, Radix};
|
use clippy_utils::numeric_literal::{NumericLiteral, Radix};
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use rustc_ast::ast::{Expr, ExprKind, LitKind};
|
use rustc_ast::ast::{Expr, ExprKind, LitKind};
|
||||||
use rustc_ast::token;
|
use rustc_ast::token;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
@ -225,7 +225,7 @@ pub fn new(conf: &'static Conf) -> Self {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_lit(&self, cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {
|
fn check_lit(&self, cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {
|
||||||
if let Some(src) = snippet_opt(cx, span)
|
if let Some(src) = span.get_source_text(cx)
|
||||||
&& let Ok(lit_kind) = LitKind::from_token_lit(lit)
|
&& let Ok(lit_kind) = LitKind::from_token_lit(lit)
|
||||||
&& let Some(mut num_lit) = NumericLiteral::from_lit_kind(&src, &lit_kind)
|
&& let Some(mut num_lit) = NumericLiteral::from_lit_kind(&src, &lit_kind)
|
||||||
{
|
{
|
||||||
@ -439,7 +439,7 @@ fn check_lit(&self, cx: &EarlyContext<'_>, lit: token::Lit, span: Span) {
|
|||||||
// Lint integral literals.
|
// Lint integral literals.
|
||||||
if let Ok(lit_kind) = LitKind::from_token_lit(lit)
|
if let Ok(lit_kind) = LitKind::from_token_lit(lit)
|
||||||
&& let LitKind::Int(val, _) = lit_kind
|
&& let LitKind::Int(val, _) = lit_kind
|
||||||
&& let Some(src) = snippet_opt(cx, span)
|
&& let Some(src) = span.get_source_text(cx)
|
||||||
&& let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit_kind)
|
&& let Some(num_lit) = NumericLiteral::from_lit_kind(&src, &lit_kind)
|
||||||
&& num_lit.radix == Radix::Decimal
|
&& num_lit.radix == Radix::Decimal
|
||||||
&& val >= u128::from(self.threshold)
|
&& val >= u128::from(self.threshold)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use clippy_utils::consts::{ConstEvalCtxt, Constant};
|
use clippy_utils::consts::{ConstEvalCtxt, Constant};
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use clippy_utils::{is_from_proc_macro, path_to_local};
|
use clippy_utils::{is_from_proc_macro, path_to_local};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
|
use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
|
||||||
@ -103,7 +103,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
|||||||
// case somebody does that for some reason
|
// case somebody does that for some reason
|
||||||
&& (is_infinity(&const_1) && is_neg_infinity(&const_2)
|
&& (is_infinity(&const_1) && is_neg_infinity(&const_2)
|
||||||
|| is_neg_infinity(&const_1) && is_infinity(&const_2))
|
|| is_neg_infinity(&const_1) && is_infinity(&const_2))
|
||||||
&& let Some(local_snippet) = snippet_opt(cx, first.span)
|
&& let Some(local_snippet) = first.span.get_source_text(cx)
|
||||||
{
|
{
|
||||||
let variant = match (kind.node, lhs_kind.node, rhs_kind.node) {
|
let variant = match (kind.node, lhs_kind.node, rhs_kind.node) {
|
||||||
(BinOpKind::Or, BinOpKind::Eq, BinOpKind::Eq) => Variant::ManualIsInfinite,
|
(BinOpKind::Or, BinOpKind::Eq, BinOpKind::Eq) => Variant::ManualIsInfinite,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use clippy_config::msrvs::{self, Msrv};
|
use clippy_config::msrvs::{self, Msrv};
|
||||||
use clippy_config::Conf;
|
use clippy_config::Conf;
|
||||||
use clippy_utils::diagnostics::span_lint_hir_and_then;
|
use clippy_utils::diagnostics::span_lint_hir_and_then;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use clippy_utils::visitors::{is_local_used, local_used_once};
|
use clippy_utils::visitors::{is_local_used, local_used_once};
|
||||||
use clippy_utils::{is_trait_method, path_to_local_id};
|
use clippy_utils::{is_trait_method, path_to_local_id};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
@ -107,8 +107,8 @@ fn check_local(&mut self, cx: &LateContext<'_>, local: &LetStmt<'_>) {
|
|||||||
finish_expr.span,
|
finish_expr.span,
|
||||||
"manual implementation of `BuildHasher::hash_one`",
|
"manual implementation of `BuildHasher::hash_one`",
|
||||||
|diag| {
|
|diag| {
|
||||||
if let Some(build_hasher) = snippet_opt(cx, build_hasher.span)
|
if let Some(build_hasher) = build_hasher.span.get_source_text(cx)
|
||||||
&& let Some(hashed_value) = snippet_opt(cx, hashed_value.span)
|
&& let Some(hashed_value) = hashed_value.span.get_source_text(cx)
|
||||||
{
|
{
|
||||||
diag.multipart_suggestion(
|
diag.multipart_suggestion(
|
||||||
"try",
|
"try",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
use clippy_config::Conf;
|
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, span_lint_hir_and_then};
|
||||||
use clippy_utils::is_doc_hidden;
|
use clippy_utils::is_doc_hidden;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use rustc_ast::ast::{self, VisibilityKind};
|
use rustc_ast::ast::{self, VisibilityKind};
|
||||||
use rustc_ast::attr;
|
use rustc_ast::attr;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
@ -124,7 +124,7 @@ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &ast::Item) {
|
|||||||
|diag| {
|
|diag| {
|
||||||
if !item.attrs.iter().any(|attr| attr.has_name(sym::non_exhaustive))
|
if !item.attrs.iter().any(|attr| attr.has_name(sym::non_exhaustive))
|
||||||
&& let header_span = cx.sess().source_map().span_until_char(item.span, delimiter)
|
&& let header_span = cx.sess().source_map().span_until_char(item.span, delimiter)
|
||||||
&& let Some(snippet) = snippet_opt(cx, header_span)
|
&& let Some(snippet) = header_span.get_source_text(cx)
|
||||||
{
|
{
|
||||||
diag.span_suggestion(
|
diag.span_suggestion(
|
||||||
header_span,
|
header_span,
|
||||||
@ -194,7 +194,7 @@ fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
|
|||||||
"this seems like a manual implementation of the non-exhaustive pattern",
|
"this seems like a manual implementation of the non-exhaustive pattern",
|
||||||
|diag| {
|
|diag| {
|
||||||
let header_span = cx.sess().source_map().span_until_char(enum_span, '{');
|
let header_span = cx.sess().source_map().span_until_char(enum_span, '{');
|
||||||
if let Some(snippet) = snippet_opt(cx, header_span) {
|
if let Some(snippet) = header_span.get_source_text(cx) {
|
||||||
diag.span_suggestion(
|
diag.span_suggestion(
|
||||||
header_span,
|
header_span,
|
||||||
"add the attribute",
|
"add the attribute",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use rustc_ast::LitKind;
|
use rustc_ast::LitKind;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
@ -143,8 +143,8 @@ fn check_pat(&mut self, cx: &LateContext<'_>, pat: &'_ rustc_hir::Pat<'_>) {
|
|||||||
pat.span,
|
pat.span,
|
||||||
"this OR pattern can be rewritten using a range",
|
"this OR pattern can be rewritten using a range",
|
||||||
|diag| {
|
|diag| {
|
||||||
if let Some(min) = snippet_opt(cx, min.span)
|
if let Some(min) = min.span.get_source_text(cx)
|
||||||
&& let Some(max) = snippet_opt(cx, max.span)
|
&& let Some(max) = max.span.get_source_text(cx)
|
||||||
{
|
{
|
||||||
diag.span_suggestion(
|
diag.span_suggestion(
|
||||||
pat.span,
|
pat.span,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use super::utils::clone_or_copy_needed;
|
use super::utils::clone_or_copy_needed;
|
||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::higher::ForLoop;
|
use clippy_utils::higher::ForLoop;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use clippy_utils::ty::{get_iterator_item_ty, implements_trait};
|
use clippy_utils::ty::{get_iterator_item_ty, implements_trait};
|
||||||
use clippy_utils::visitors::for_each_expr_without_closures;
|
use clippy_utils::visitors::for_each_expr_without_closures;
|
||||||
use clippy_utils::{can_mut_borrow_both, fn_def_id, get_parent_expr, path_to_local};
|
use clippy_utils::{can_mut_borrow_both, fn_def_id, get_parent_expr, path_to_local};
|
||||||
@ -40,7 +40,7 @@ pub fn check_for_loop_iter(
|
|||||||
&& let Some(ForLoop { pat, body, .. }) = ForLoop::hir(grandparent)
|
&& let Some(ForLoop { pat, body, .. }) = ForLoop::hir(grandparent)
|
||||||
&& let (clone_or_copy_needed, references_to_binding) = clone_or_copy_needed(cx, pat, body)
|
&& let (clone_or_copy_needed, references_to_binding) = clone_or_copy_needed(cx, pat, body)
|
||||||
&& !clone_or_copy_needed
|
&& !clone_or_copy_needed
|
||||||
&& let Some(receiver_snippet) = snippet_opt(cx, receiver.span)
|
&& let Some(receiver_snippet) = receiver.span.get_source_text(cx)
|
||||||
{
|
{
|
||||||
// Issue 12098
|
// Issue 12098
|
||||||
// https://github.com/rust-lang/rust-clippy/issues/12098
|
// https://github.com/rust-lang/rust-clippy/issues/12098
|
||||||
@ -100,7 +100,7 @@ fn is_caller_or_fields_change(cx: &LateContext<'_>, body: &Expr<'_>, caller: &Ex
|
|||||||
&& implements_trait(cx, collection_ty, into_iterator_trait_id, &[])
|
&& implements_trait(cx, collection_ty, into_iterator_trait_id, &[])
|
||||||
&& let Some(into_iter_item_ty) = cx.get_associated_type(collection_ty, into_iterator_trait_id, "Item")
|
&& let Some(into_iter_item_ty) = cx.get_associated_type(collection_ty, into_iterator_trait_id, "Item")
|
||||||
&& iter_item_ty == into_iter_item_ty
|
&& iter_item_ty == into_iter_item_ty
|
||||||
&& let Some(collection_snippet) = snippet_opt(cx, collection.span)
|
&& let Some(collection_snippet) = collection.span.get_source_text(cx)
|
||||||
{
|
{
|
||||||
collection_snippet
|
collection_snippet
|
||||||
} else {
|
} else {
|
||||||
@ -122,7 +122,7 @@ fn is_caller_or_fields_change(cx: &LateContext<'_>, body: &Expr<'_>, caller: &Ex
|
|||||||
} else {
|
} else {
|
||||||
Applicability::MachineApplicable
|
Applicability::MachineApplicable
|
||||||
};
|
};
|
||||||
diag.span_suggestion(expr.span, "use", snippet, applicability);
|
diag.span_suggestion(expr.span, "use", snippet.to_owned(), applicability);
|
||||||
if !references_to_binding.is_empty() {
|
if !references_to_binding.is_empty() {
|
||||||
diag.multipart_suggestion(
|
diag.multipart_suggestion(
|
||||||
"remove any references to the binding",
|
"remove any references to the binding",
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
|
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
|
use itertools::Itertools;
|
||||||
use rustc_ast::ast::{Pat, PatKind};
|
use rustc_ast::ast::{Pat, PatKind};
|
||||||
use rustc_lint::EarlyContext;
|
use rustc_lint::EarlyContext;
|
||||||
|
|
||||||
@ -45,19 +46,6 @@ pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
|
|||||||
"you matched a field with a wildcard pattern, consider using `..` instead",
|
"you matched a field with a wildcard pattern, consider using `..` instead",
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let mut normal = vec![];
|
|
||||||
|
|
||||||
for field in pfields {
|
|
||||||
match field.pat.kind {
|
|
||||||
PatKind::Wild => {},
|
|
||||||
_ => {
|
|
||||||
if let Some(n) = snippet_opt(cx, field.span) {
|
|
||||||
normal.push(n);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
#[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
|
||||||
span_lint_and_then(
|
span_lint_and_then(
|
||||||
cx,
|
cx,
|
||||||
@ -65,7 +53,16 @@ pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
|
|||||||
field.span,
|
field.span,
|
||||||
"you matched a field with a wildcard pattern, consider using `..` instead",
|
"you matched a field with a wildcard pattern, consider using `..` instead",
|
||||||
|diag| {
|
|diag| {
|
||||||
diag.help(format!("try with `{type_name} {{ {}, .. }}`", normal[..].join(", ")));
|
diag.help(format!(
|
||||||
|
"try with `{type_name} {{ {}, .. }}`",
|
||||||
|
pfields
|
||||||
|
.iter()
|
||||||
|
.filter_map(|f| match f.pat.kind {
|
||||||
|
PatKind::Wild => None,
|
||||||
|
_ => f.span.get_source_text(cx),
|
||||||
|
})
|
||||||
|
.format(", "),
|
||||||
|
));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use clippy_config::Conf;
|
use clippy_config::Conf;
|
||||||
use clippy_utils::def_path_def_ids;
|
use clippy_utils::def_path_def_ids;
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::def::Res;
|
use rustc_hir::def::Res;
|
||||||
use rustc_hir::def_id::DefIdMap;
|
use rustc_hir::def_id::DefIdMap;
|
||||||
@ -73,7 +73,7 @@ fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
|
|||||||
&& let Some(name) = self.renames.get(&id)
|
&& let Some(name) = self.renames.get(&id)
|
||||||
// Remove semicolon since it is not present for nested imports
|
// Remove semicolon since it is not present for nested imports
|
||||||
&& let span_without_semi = cx.sess().source_map().span_until_char(item.span, ';')
|
&& let span_without_semi = cx.sess().source_map().span_until_char(item.span, ';')
|
||||||
&& let Some(snip) = snippet_opt(cx, span_without_semi)
|
&& let Some(snip) = span_without_semi.get_source_text(cx)
|
||||||
&& let Some(import) = match snip.split_once(" as ") {
|
&& let Some(import) = match snip.split_once(" as ") {
|
||||||
None => Some(snip.as_str()),
|
None => Some(snip.as_str()),
|
||||||
Some((import, rename)) => {
|
Some((import, rename)) => {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::higher::If;
|
use clippy_utils::higher::If;
|
||||||
use clippy_utils::is_from_proc_macro;
|
use clippy_utils::is_from_proc_macro;
|
||||||
use clippy_utils::source::{snippet_opt, SpanRangeExt};
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{ExprKind, Stmt, StmtKind};
|
use rustc_hir::{ExprKind, Stmt, StmtKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
@ -57,7 +57,7 @@ fn check_stmt<'tcx>(&mut self, cx: &LateContext<'tcx>, stmt: &Stmt<'tcx>) {
|
|||||||
src.bytes()
|
src.bytes()
|
||||||
.all(|ch| matches!(ch, b'{' | b'}') || ch.is_ascii_whitespace())
|
.all(|ch| matches!(ch, b'{' | b'}') || ch.is_ascii_whitespace())
|
||||||
})
|
})
|
||||||
&& let Some(cond_snippet) = snippet_opt(cx, cond.span)
|
&& let Some(cond_snippet) = cond.span.get_source_text(cx)
|
||||||
&& !is_from_proc_macro(cx, expr)
|
&& !is_from_proc_macro(cx, expr)
|
||||||
{
|
{
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::path_to_local;
|
use clippy_utils::path_to_local;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::{SourceText, SpanRangeExt};
|
||||||
use clippy_utils::ty::needs_ordered_drop;
|
use clippy_utils::ty::needs_ordered_drop;
|
||||||
use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures, is_local_used};
|
use clippy_utils::visitors::{for_each_expr, for_each_expr_without_closures, is_local_used};
|
||||||
use core::ops::ControlFlow;
|
use core::ops::ControlFlow;
|
||||||
@ -236,7 +236,7 @@ fn first_usage<'tcx>(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &LetStmt<'_>) -> Option<String> {
|
fn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &LetStmt<'_>) -> Option<SourceText> {
|
||||||
let span = local.span.with_hi(match local.ty {
|
let span = local.span.with_hi(match local.ty {
|
||||||
// let <pat>: <ty>;
|
// let <pat>: <ty>;
|
||||||
// ~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~
|
||||||
@ -246,7 +246,7 @@ fn local_snippet_without_semicolon(cx: &LateContext<'_>, local: &LetStmt<'_>) ->
|
|||||||
None => local.pat.span.hi(),
|
None => local.pat.span.hi(),
|
||||||
});
|
});
|
||||||
|
|
||||||
snippet_opt(cx, span)
|
span.get_source_text(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check<'tcx>(
|
fn check<'tcx>(
|
||||||
@ -275,7 +275,10 @@ fn check<'tcx>(
|
|||||||
|diag| {
|
|diag| {
|
||||||
diag.multipart_suggestion(
|
diag.multipart_suggestion(
|
||||||
format!("move the declaration `{binding_name}` here"),
|
format!("move the declaration `{binding_name}` here"),
|
||||||
vec![(local_stmt.span, String::new()), (assign.lhs_span, let_snippet)],
|
vec![
|
||||||
|
(local_stmt.span, String::new()),
|
||||||
|
(assign.lhs_span, let_snippet.to_owned()),
|
||||||
|
],
|
||||||
Applicability::MachineApplicable,
|
Applicability::MachineApplicable,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
|
use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use clippy_utils::ty::has_drop;
|
use clippy_utils::ty::has_drop;
|
||||||
use clippy_utils::{
|
use clippy_utils::{
|
||||||
in_automatically_derived, is_inside_always_const_context, is_lint_allowed, path_to_local, peel_blocks,
|
in_automatically_derived, is_inside_always_const_context, is_lint_allowed, path_to_local, peel_blocks,
|
||||||
@ -268,15 +268,11 @@ fn check_unnecessary_operation(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
|
|||||||
&& reduced.iter().all(|e| e.span.ctxt() == ctxt)
|
&& reduced.iter().all(|e| e.span.ctxt() == ctxt)
|
||||||
{
|
{
|
||||||
if let ExprKind::Index(..) = &expr.kind {
|
if let ExprKind::Index(..) = &expr.kind {
|
||||||
if is_inside_always_const_context(cx.tcx, expr.hir_id) {
|
if !is_inside_always_const_context(cx.tcx, expr.hir_id)
|
||||||
return;
|
&& let [arr, func] = &*reduced
|
||||||
}
|
&& let Some(arr) = arr.span.get_source_text(cx)
|
||||||
let snippet =
|
&& let Some(func) = func.span.get_source_text(cx)
|
||||||
if let (Some(arr), Some(func)) = (snippet_opt(cx, reduced[0].span), snippet_opt(cx, reduced[1].span)) {
|
{
|
||||||
format!("assert!({arr}.len() > {func});")
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
span_lint_hir_and_then(
|
span_lint_hir_and_then(
|
||||||
cx,
|
cx,
|
||||||
UNNECESSARY_OPERATION,
|
UNNECESSARY_OPERATION,
|
||||||
@ -287,15 +283,16 @@ fn check_unnecessary_operation(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
|
|||||||
diag.span_suggestion(
|
diag.span_suggestion(
|
||||||
stmt.span,
|
stmt.span,
|
||||||
"statement can be written as",
|
"statement can be written as",
|
||||||
snippet,
|
format!("assert!({arr}.len() > {func});"),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut snippet = String::new();
|
let mut snippet = String::new();
|
||||||
for e in reduced {
|
for e in reduced {
|
||||||
if let Some(snip) = snippet_opt(cx, e.span) {
|
if let Some(snip) = e.span.get_source_text(cx) {
|
||||||
snippet.push_str(&snip);
|
snippet.push_str(&snip);
|
||||||
snippet.push(';');
|
snippet.push(';');
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use clippy_config::types::MacroMatcher;
|
use clippy_config::types::MacroMatcher;
|
||||||
use clippy_config::Conf;
|
use clippy_config::Conf;
|
||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::{SourceText, SpanRangeExt};
|
||||||
use rustc_ast::ast;
|
use rustc_ast::ast;
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
@ -34,7 +34,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The (callsite span, (open brace, close brace), source snippet)
|
/// The (callsite span, (open brace, close brace), source snippet)
|
||||||
type MacroInfo = (Span, (char, char), String);
|
type MacroInfo = (Span, (char, char), SourceText);
|
||||||
|
|
||||||
pub struct MacroBraces {
|
pub struct MacroBraces {
|
||||||
macro_braces: FxHashMap<String, (char, char)>,
|
macro_braces: FxHashMap<String, (char, char)>,
|
||||||
@ -94,7 +94,7 @@ fn is_offending_macro(cx: &EarlyContext<'_>, span: Span, mac_braces: &MacroBrace
|
|||||||
if let ExpnKind::Macro(MacroKind::Bang, mac_name) = span.ctxt().outer_expn_data().kind
|
if let ExpnKind::Macro(MacroKind::Bang, mac_name) = span.ctxt().outer_expn_data().kind
|
||||||
&& let name = mac_name.as_str()
|
&& let name = mac_name.as_str()
|
||||||
&& let Some(&braces) = mac_braces.macro_braces.get(name)
|
&& let Some(&braces) = mac_braces.macro_braces.get(name)
|
||||||
&& let Some(snip) = snippet_opt(cx, span_call_site)
|
&& let Some(snip) = span_call_site.get_source_text(cx)
|
||||||
// we must check only invocation sites
|
// we must check only invocation sites
|
||||||
// https://github.com/rust-lang/rust-clippy/issues/7422
|
// https://github.com/rust-lang/rust-clippy/issues/7422
|
||||||
&& snip.starts_with(&format!("{name}!"))
|
&& snip.starts_with(&format!("{name}!"))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use clippy_utils::ty::implements_trait;
|
use clippy_utils::ty::implements_trait;
|
||||||
use clippy_utils::visitors::for_each_expr_without_closures;
|
use clippy_utils::visitors::for_each_expr_without_closures;
|
||||||
use clippy_utils::{binop_traits, eq_expr_value, trait_ref_of_method};
|
use clippy_utils::{binop_traits, eq_expr_value, trait_ref_of_method};
|
||||||
@ -46,8 +46,8 @@ pub(super) fn check<'tcx>(
|
|||||||
expr.span,
|
expr.span,
|
||||||
"manual implementation of an assign operation",
|
"manual implementation of an assign operation",
|
||||||
|diag| {
|
|diag| {
|
||||||
if let (Some(snip_a), Some(snip_r)) =
|
if let Some(snip_a) = assignee.span.get_source_text(cx)
|
||||||
(snippet_opt(cx, assignee.span), snippet_opt(cx, rhs.span))
|
&& let Some(snip_r) = rhs.span.get_source_text(cx)
|
||||||
{
|
{
|
||||||
diag.span_suggestion(
|
diag.span_suggestion(
|
||||||
expr.span,
|
expr.span,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use clippy_utils::{eq_expr_value, sugg};
|
use clippy_utils::{eq_expr_value, sugg};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
@ -42,7 +42,9 @@ fn lint_misrefactored_assign_op(
|
|||||||
expr.span,
|
expr.span,
|
||||||
"variable appears on both sides of an assignment operation",
|
"variable appears on both sides of an assignment operation",
|
||||||
|diag| {
|
|diag| {
|
||||||
if let (Some(snip_a), Some(snip_r)) = (snippet_opt(cx, assignee.span), snippet_opt(cx, rhs_other.span)) {
|
if let Some(snip_a) = assignee.span.get_source_text(cx)
|
||||||
|
&& let Some(snip_r) = rhs_other.span.get_source_text(cx)
|
||||||
|
{
|
||||||
let a = &sugg::Sugg::hir(cx, assignee, "..");
|
let a = &sugg::Sugg::hir(cx, assignee, "..");
|
||||||
let r = &sugg::Sugg::hir(cx, rhs, "..");
|
let r = &sugg::Sugg::hir(cx, rhs, "..");
|
||||||
let long = format!("{snip_a} = {}", sugg::make_binop(op, a, r));
|
let long = format!("{snip_a} = {}", sugg::make_binop(op, a, r));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
@ -24,8 +24,8 @@ pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, op: BinOpKind, lhs: &Exp
|
|||||||
e.span,
|
e.span,
|
||||||
"use of bitwise operator instead of lazy operator between booleans",
|
"use of bitwise operator instead of lazy operator between booleans",
|
||||||
|diag| {
|
|diag| {
|
||||||
if let Some(lhs_snip) = snippet_opt(cx, lhs.span)
|
if let Some(lhs_snip) = lhs.span.get_source_text(cx)
|
||||||
&& let Some(rhs_snip) = snippet_opt(cx, rhs.span)
|
&& let Some(rhs_snip) = rhs.span.get_source_text(cx)
|
||||||
{
|
{
|
||||||
let sugg = format!("{lhs_snip} {op_str} {rhs_snip}");
|
let sugg = format!("{lhs_snip} {op_str} {rhs_snip}");
|
||||||
diag.span_suggestion(e.span, "try", sugg, Applicability::MachineApplicable);
|
diag.span_suggestion(e.span, "try", sugg, Applicability::MachineApplicable);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use clippy_utils::std_or_core;
|
use clippy_utils::std_or_core;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
||||||
@ -22,8 +22,8 @@ pub(super) fn check<'tcx>(
|
|||||||
|
|
||||||
if let Some(left_var) = expr_as_cast_to_raw_pointer(cx, left)
|
if let Some(left_var) = expr_as_cast_to_raw_pointer(cx, left)
|
||||||
&& let Some(right_var) = expr_as_cast_to_raw_pointer(cx, right)
|
&& let Some(right_var) = expr_as_cast_to_raw_pointer(cx, right)
|
||||||
&& let Some(left_snip) = snippet_opt(cx, left_var.span)
|
&& let Some(left_snip) = left_var.span.get_source_text(cx)
|
||||||
&& let Some(right_snip) = snippet_opt(cx, right_var.span)
|
&& let Some(right_snip) = right_var.span.get_source_text(cx)
|
||||||
{
|
{
|
||||||
let Some(top_crate) = std_or_core(cx) else { return };
|
let Some(top_crate) = std_or_core(cx) else { return };
|
||||||
span_lint_and_sugg(
|
span_lint_and_sugg(
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_then;
|
use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::is_from_proc_macro;
|
use clippy_utils::is_from_proc_macro;
|
||||||
use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
|
use clippy_utils::source::{indent_of, reindent_multiline, SourceText, SpanRangeExt};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{Block, Expr, ExprKind, MatchSource, Node, StmtKind};
|
use rustc_hir::{Block, Expr, ExprKind, MatchSource, Node, StmtKind};
|
||||||
use rustc_lint::LateContext;
|
use rustc_lint::LateContext;
|
||||||
@ -79,7 +79,7 @@ fn lint_unit_args(cx: &LateContext<'_>, expr: &Expr<'_>, args_to_recover: &[&Exp
|
|||||||
&& block.expr.is_none()
|
&& block.expr.is_none()
|
||||||
&& let Some(last_stmt) = block.stmts.iter().last()
|
&& let Some(last_stmt) = block.stmts.iter().last()
|
||||||
&& let StmtKind::Semi(last_expr) = last_stmt.kind
|
&& let StmtKind::Semi(last_expr) = last_stmt.kind
|
||||||
&& let Some(snip) = snippet_opt(cx, last_expr.span)
|
&& let Some(snip) = last_expr.span.get_source_text(cx)
|
||||||
{
|
{
|
||||||
Some((last_stmt.span, snip))
|
Some((last_stmt.span, snip))
|
||||||
} else {
|
} else {
|
||||||
@ -90,24 +90,24 @@ fn lint_unit_args(cx: &LateContext<'_>, expr: &Expr<'_>, args_to_recover: &[&Exp
|
|||||||
db.span_suggestion(
|
db.span_suggestion(
|
||||||
span,
|
span,
|
||||||
"remove the semicolon from the last statement in the block",
|
"remove the semicolon from the last statement in the block",
|
||||||
sugg,
|
sugg.as_str(),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
or = "or ";
|
or = "or ";
|
||||||
applicability = Applicability::MaybeIncorrect;
|
applicability = Applicability::MaybeIncorrect;
|
||||||
});
|
});
|
||||||
|
|
||||||
let arg_snippets: Vec<String> = args_to_recover
|
let arg_snippets: Vec<_> = args_to_recover
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|arg| snippet_opt(cx, arg.span))
|
.filter_map(|arg| arg.span.get_source_text(cx))
|
||||||
.collect();
|
.collect();
|
||||||
let arg_snippets_without_empty_blocks: Vec<String> = args_to_recover
|
let arg_snippets_without_empty_blocks: Vec<_> = args_to_recover
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|arg| !is_empty_block(arg))
|
.filter(|arg| !is_empty_block(arg))
|
||||||
.filter_map(|arg| snippet_opt(cx, arg.span))
|
.filter_map(|arg| arg.span.get_source_text(cx))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
if let Some(call_snippet) = snippet_opt(cx, expr.span) {
|
if let Some(call_snippet) = expr.span.get_source_text(cx) {
|
||||||
let sugg = fmt_stmts_and_call(
|
let sugg = fmt_stmts_and_call(
|
||||||
cx,
|
cx,
|
||||||
expr,
|
expr,
|
||||||
@ -161,8 +161,8 @@ fn fmt_stmts_and_call(
|
|||||||
cx: &LateContext<'_>,
|
cx: &LateContext<'_>,
|
||||||
call_expr: &Expr<'_>,
|
call_expr: &Expr<'_>,
|
||||||
call_snippet: &str,
|
call_snippet: &str,
|
||||||
args_snippets: &[impl AsRef<str>],
|
args_snippets: &[SourceText],
|
||||||
non_empty_block_args_snippets: &[impl AsRef<str>],
|
non_empty_block_args_snippets: &[SourceText],
|
||||||
) -> String {
|
) -> String {
|
||||||
let call_expr_indent = indent_of(cx, call_expr.span).unwrap_or(0);
|
let call_expr_indent = indent_of(cx, call_expr.span).unwrap_or(0);
|
||||||
let call_snippet_with_replacements = args_snippets
|
let call_snippet_with_replacements = args_snippets
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use clippy_utils::macros::FormatArgsStorage;
|
use clippy_utils::macros::FormatArgsStorage;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::SpanRangeExt;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustc_ast::{Crate, Expr, ExprKind, FormatArgs};
|
use rustc_ast::{Crate, Expr, ExprKind, FormatArgs};
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
@ -75,38 +75,21 @@ fn has_span_from_proc_macro(cx: &EarlyContext<'_>, args: &FormatArgs) -> bool {
|
|||||||
|
|
||||||
// `format!("{} {} {c}", "one", "two", c = "three")`
|
// `format!("{} {} {c}", "one", "two", c = "three")`
|
||||||
// ^^ ^^ ^^^^^^
|
// ^^ ^^ ^^^^^^
|
||||||
let between_spans = once(args.span)
|
!once(args.span)
|
||||||
.chain(argument_span)
|
.chain(argument_span)
|
||||||
.tuple_windows()
|
.tuple_windows()
|
||||||
.map(|(start, end)| start.between(end));
|
.map(|(start, end)| start.between(end))
|
||||||
|
.all(|sp| {
|
||||||
for between_span in between_spans {
|
sp.check_source_text(cx, |src| {
|
||||||
let mut seen_comma = false;
|
// text should be either `, name` or `, name =`
|
||||||
|
let mut iter = tokenize(src).filter(|t| {
|
||||||
let Some(snippet) = snippet_opt(cx, between_span) else {
|
!matches!(
|
||||||
return true;
|
t.kind,
|
||||||
};
|
TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace
|
||||||
for token in tokenize(&snippet) {
|
)
|
||||||
match token.kind {
|
});
|
||||||
TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace => {},
|
iter.next().is_some_and(|t| matches!(t.kind, TokenKind::Comma))
|
||||||
TokenKind::Comma if !seen_comma => seen_comma = true,
|
&& iter.all(|t| matches!(t.kind, TokenKind::Ident | TokenKind::Eq))
|
||||||
// named arguments, `start_val, name = end_val`
|
})
|
||||||
// ^^^^^^^^^ between_span
|
})
|
||||||
TokenKind::Ident | TokenKind::Eq if seen_comma => {},
|
|
||||||
// An unexpected token usually indicates that we crossed a macro boundary
|
|
||||||
//
|
|
||||||
// `println!(some_proc_macro!("input {}"), a)`
|
|
||||||
// ^^^ between_span
|
|
||||||
// `println!("{}", val!(x))`
|
|
||||||
// ^^^^^^^ between_span
|
|
||||||
_ => return true,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !seen_comma {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
use rustc_span::{sym, Span};
|
use rustc_span::{sym, Span};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use crate::source::snippet_opt;
|
use crate::source::SpanRangeExt;
|
||||||
use crate::tokenize_with_text;
|
use crate::tokenize_with_text;
|
||||||
|
|
||||||
/// Deprecation status of attributes known by Clippy.
|
/// Deprecation status of attributes known by Clippy.
|
||||||
@ -179,11 +179,8 @@ pub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool {
|
|||||||
|
|
||||||
/// Checks if the given span contains a `#[cfg(..)]` attribute
|
/// Checks if the given span contains a `#[cfg(..)]` attribute
|
||||||
pub fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool {
|
pub fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool {
|
||||||
let Some(snip) = snippet_opt(cx, s) else {
|
s.check_source_text(cx, |src| {
|
||||||
// Assume true. This would require either an invalid span, or one which crosses file boundaries.
|
let mut iter = tokenize_with_text(src);
|
||||||
return true;
|
|
||||||
};
|
|
||||||
let mut iter = tokenize_with_text(&snip);
|
|
||||||
|
|
||||||
// Search for the token sequence [`#`, `[`, `cfg`]
|
// Search for the token sequence [`#`, `[`, `cfg`]
|
||||||
while iter.any(|(t, _)| matches!(t, TokenKind::Pound)) {
|
while iter.any(|(t, _)| matches!(t, TokenKind::Pound)) {
|
||||||
@ -200,4 +197,5 @@ pub fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::consts::ConstEvalCtxt;
|
use crate::consts::ConstEvalCtxt;
|
||||||
use crate::macros::macro_backtrace;
|
use crate::macros::macro_backtrace;
|
||||||
use crate::source::{snippet_opt, walk_span_to_context, SpanRange, SpanRangeExt};
|
use crate::source::{walk_span_to_context, SpanRange, SpanRangeExt};
|
||||||
use crate::tokenize_with_text;
|
use crate::tokenize_with_text;
|
||||||
use rustc_ast::ast::InlineAsmTemplatePiece;
|
use rustc_ast::ast::InlineAsmTemplatePiece;
|
||||||
use rustc_data_structures::fx::FxHasher;
|
use rustc_data_structures::fx::FxHasher;
|
||||||
@ -588,10 +588,9 @@ fn reduce_exprkind<'hir>(cx: &LateContext<'_>, kind: &'hir ExprKind<'hir>) -> &'
|
|||||||
// block with an empty span.
|
// block with an empty span.
|
||||||
([], None) if block.span.is_empty() => &ExprKind::Tup(&[]),
|
([], None) if block.span.is_empty() => &ExprKind::Tup(&[]),
|
||||||
// `{}` => `()`
|
// `{}` => `()`
|
||||||
([], None) => match snippet_opt(cx, block.span) {
|
([], None)
|
||||||
// Don't reduce if there are any tokens contained in the braces
|
if block.span.check_source_text(cx, |src| {
|
||||||
Some(snip)
|
tokenize(src)
|
||||||
if tokenize(&snip)
|
|
||||||
.map(|t| t.kind)
|
.map(|t| t.kind)
|
||||||
.filter(|t| {
|
.filter(|t| {
|
||||||
!matches!(
|
!matches!(
|
||||||
@ -599,11 +598,10 @@ fn reduce_exprkind<'hir>(cx: &LateContext<'_>, kind: &'hir ExprKind<'hir>) -> &'
|
|||||||
TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace
|
TokenKind::LineComment { .. } | TokenKind::BlockComment { .. } | TokenKind::Whitespace
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.ne([TokenKind::OpenBrace, TokenKind::CloseBrace].iter().copied()) =>
|
.eq([TokenKind::OpenBrace, TokenKind::CloseBrace].iter().copied())
|
||||||
|
}) =>
|
||||||
{
|
{
|
||||||
kind
|
&ExprKind::Tup(&[])
|
||||||
},
|
|
||||||
_ => &ExprKind::Tup(&[]),
|
|
||||||
},
|
},
|
||||||
([], Some(expr)) => match expr.kind {
|
([], Some(expr)) => match expr.kind {
|
||||||
// `{ return .. }` => `return ..`
|
// `{ return .. }` => `return ..`
|
||||||
|
Loading…
Reference in New Issue
Block a user