mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-28 03:07:24 +03:00
fix(explicit_counter_loop): suggest .take(n) for for _ in 0..n counter loops
fix(explicit_counter_loop): suggest `.take(n)` for `for _ in 0..n` counter loops
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
use super::{EXPLICIT_COUNTER_LOOP, IncrementVisitor, InitializeVisitor, make_iterator_snippet};
|
||||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::higher::Range;
|
||||
use clippy_utils::source::snippet_with_applicability;
|
||||
use clippy_utils::sugg::{EMPTY, Sugg};
|
||||
use clippy_utils::{get_enclosing_block, is_integer_const, is_integer_literal_untyped};
|
||||
@@ -83,6 +84,26 @@ pub(super) fn check<'tcx>(
|
||||
snippet
|
||||
});
|
||||
|
||||
// If the loop variable is unused and the range is `0..n`, suggest `(init..).take(n)`.
|
||||
if pat_snippet == "_"
|
||||
&& let Some(range) = Range::hir(cx, arg)
|
||||
&& range.limits == RangeLimits::HalfOpen
|
||||
&& range.start.is_some_and(|start| is_integer_const(cx, start, 0))
|
||||
&& let Some(end) = range.end
|
||||
{
|
||||
let end = snippet_with_applicability(cx, end.span, "..", &mut applicability);
|
||||
diag.span_suggestion(
|
||||
span,
|
||||
"consider using",
|
||||
format!(
|
||||
"{loop_label}for {name} in ({}).take({end})",
|
||||
initializer.range(&EMPTY, RangeLimits::HalfOpen)
|
||||
),
|
||||
applicability,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
diag.span_suggestion(
|
||||
span,
|
||||
"consider using",
|
||||
|
||||
@@ -332,3 +332,34 @@ fn add_assign(&mut self, rhs: u8) {
|
||||
priority += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn issue_16642() {
|
||||
let mut base = 100;
|
||||
const MAX: usize = 10;
|
||||
for _ in 0..MAX {
|
||||
//~^ explicit_counter_loop
|
||||
base += 1;
|
||||
}
|
||||
|
||||
let mut base = 100;
|
||||
|
||||
let nums = vec![1, 2, 3, 4];
|
||||
for _ in nums {
|
||||
//~^ explicit_counter_loop
|
||||
base += 1;
|
||||
}
|
||||
|
||||
// inclusive range: should not suggest .take()
|
||||
let mut base = 100;
|
||||
for _ in 0..=MAX {
|
||||
//~^ explicit_counter_loop
|
||||
base += 1;
|
||||
}
|
||||
|
||||
// non-zero start: should not suggest .take(), falls through to zip
|
||||
let mut base = 100;
|
||||
for _ in 5..MAX {
|
||||
//~^ explicit_counter_loop
|
||||
base += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,5 +81,29 @@ error: the variable `j` is used as a loop counter
|
||||
LL | for item in &v {
|
||||
| ^^^^^^^^^^^^^^ help: consider using: `for (j, item) in (s + 1..).zip(v.iter())`
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
error: the variable `base` is used as a loop counter
|
||||
--> tests/ui/explicit_counter_loop.rs:339:5
|
||||
|
|
||||
LL | for _ in 0..MAX {
|
||||
| ^^^^^^^^^^^^^^^ help: consider using: `for base in (100..).take(MAX)`
|
||||
|
||||
error: the variable `base` is used as a loop counter
|
||||
--> tests/ui/explicit_counter_loop.rs:347:5
|
||||
|
|
||||
LL | for _ in nums {
|
||||
| ^^^^^^^^^^^^^ help: consider using: `for (base, _) in (100..).zip(nums.into_iter())`
|
||||
|
||||
error: the variable `base` is used as a loop counter
|
||||
--> tests/ui/explicit_counter_loop.rs:354:5
|
||||
|
|
||||
LL | for _ in 0..=MAX {
|
||||
| ^^^^^^^^^^^^^^^^ help: consider using: `for (base, _) in (100..).zip((0..=MAX))`
|
||||
|
||||
error: the variable `base` is used as a loop counter
|
||||
--> tests/ui/explicit_counter_loop.rs:361:5
|
||||
|
|
||||
LL | for _ in 5..MAX {
|
||||
| ^^^^^^^^^^^^^^^ help: consider using: `for (base, _) in (100..).zip((5..MAX))`
|
||||
|
||||
error: aborting due to 17 previous errors
|
||||
|
||||
|
||||
Reference in New Issue
Block a user