Auto merge of #11862 - christophbeberweil:7125-single-element-loop-over-range, r=llogiq
suggest alternatives to iterate an array of ranges works towards #7125 changelog: [`single_element_loop`]: suggest better syntax when iterating over an array of a single range `@thinkerdreamer` and myself worked on this issue during a workshop by `@llogiq` at the RustLab 2023 conference. It is our first contribution to clippy. When iterating over an array of only one element, _which is a range_, our change suggests to replace the array with the contained range itself. Additionally, a hint is printed stating that the user probably intended to iterate over the range and not the array. If the single element in the array is not a range, the previous suggestion in the form of `let {pat_snip} = {prefix}{arg_snip};{block_str}`is used. This change lints the array with the single range directly, so any prefixes or suffixes are covered as well.
This commit is contained in:
commit
6cfbe57075
3 changed files with 45 additions and 74 deletions
|
|
@ -1,6 +1,6 @@
|
|||
use super::SINGLE_ELEMENT_LOOP;
|
||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||
use clippy_utils::source::{indent_of, snippet_with_applicability};
|
||||
use clippy_utils::source::{indent_of, snippet, snippet_with_applicability};
|
||||
use clippy_utils::visitors::contains_break_or_continue;
|
||||
use rustc_ast::util::parser::PREC_PREFIX;
|
||||
use rustc_ast::Mutability;
|
||||
|
|
@ -87,14 +87,29 @@ pub(super) fn check<'tcx>(
|
|||
arg_snip = format!("({arg_snip})").into();
|
||||
}
|
||||
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
SINGLE_ELEMENT_LOOP,
|
||||
expr.span,
|
||||
"for loop over a single element",
|
||||
"try",
|
||||
format!("{{\n{indent}let {pat_snip} = {prefix}{arg_snip};{block_str}}}"),
|
||||
applicability,
|
||||
);
|
||||
if clippy_utils::higher::Range::hir(arg_expression).is_some() {
|
||||
let range_expr = snippet(cx, arg_expression.span, "?").to_string();
|
||||
|
||||
let sugg = snippet(cx, arg_expression.span, "..");
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
SINGLE_ELEMENT_LOOP,
|
||||
arg.span,
|
||||
format!("this loops only once with `{pat_snip}` being `{range_expr}`").as_str(),
|
||||
"did you mean to iterate over the range instead?",
|
||||
sugg.to_string(),
|
||||
Applicability::Unspecified,
|
||||
);
|
||||
} else {
|
||||
span_lint_and_sugg(
|
||||
cx,
|
||||
SINGLE_ELEMENT_LOOP,
|
||||
expr.span,
|
||||
"for loop over a single element",
|
||||
"try",
|
||||
format!("{{\n{indent}let {pat_snip} = {prefix}{arg_snip};{block_str}}}"),
|
||||
applicability,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue