Skip to content

Commit 0f2b119

Browse files
committed
Remove reverse_range_loop lint
1 parent 8ffa0bf commit 0f2b119

10 files changed

+32
-311
lines changed

Diff for: CHANGELOG.md

-1
Original file line numberDiff line numberDiff line change
@@ -1545,7 +1545,6 @@ Released 2018-09-13
15451545
[`result_map_unit_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_unit_fn
15461546
[`result_map_unwrap_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_map_unwrap_or_else
15471547
[`result_unwrap_used`]: https://rust-lang.github.io/rust-clippy/master/index.html#result_unwrap_used
1548-
[`reverse_range_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#reverse_range_loop
15491548
[`reversed_empty_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#reversed_empty_ranges
15501549
[`same_functions_in_if_condition`]: https://rust-lang.github.io/rust-clippy/master/index.html#same_functions_in_if_condition
15511550
[`search_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#search_is_some

Diff for: clippy_lints/src/lib.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
624624
&loops::NEEDLESS_COLLECT,
625625
&loops::NEEDLESS_RANGE_LOOP,
626626
&loops::NEVER_LOOP,
627-
&loops::REVERSE_RANGE_LOOP,
628627
&loops::WHILE_IMMUTABLE_CONDITION,
629628
&loops::WHILE_LET_LOOP,
630629
&loops::WHILE_LET_ON_ITERATOR,
@@ -1284,7 +1283,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
12841283
LintId::of(&loops::NEEDLESS_COLLECT),
12851284
LintId::of(&loops::NEEDLESS_RANGE_LOOP),
12861285
LintId::of(&loops::NEVER_LOOP),
1287-
LintId::of(&loops::REVERSE_RANGE_LOOP),
12881286
LintId::of(&loops::WHILE_IMMUTABLE_CONDITION),
12891287
LintId::of(&loops::WHILE_LET_LOOP),
12901288
LintId::of(&loops::WHILE_LET_ON_ITERATOR),
@@ -1658,7 +1656,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
16581656
LintId::of(&loops::FOR_LOOP_OVER_RESULT),
16591657
LintId::of(&loops::ITER_NEXT_LOOP),
16601658
LintId::of(&loops::NEVER_LOOP),
1661-
LintId::of(&loops::REVERSE_RANGE_LOOP),
16621659
LintId::of(&loops::WHILE_IMMUTABLE_CONDITION),
16631660
LintId::of(&mem_discriminant::MEM_DISCRIMINANT_NON_ENUM),
16641661
LintId::of(&mem_replace::MEM_REPLACE_WITH_UNINIT),
@@ -1788,6 +1785,10 @@ fn register_removed_non_tool_lints(store: &mut rustc_lint::LintStore) {
17881785
"unsafe_vector_initialization",
17891786
"the replacement suggested by this lint had substantially different behavior",
17901787
);
1788+
store.register_removed(
1789+
"reverse_range_loop",
1790+
"this lint is now included in reversed_empty_ranges",
1791+
);
17911792
}
17921793

17931794
/// Register renamed lints.

Diff for: clippy_lints/src/loops.rs

+2-100
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::consts::{constant, Constant};
1+
use crate::consts::constant;
22
use crate::reexport::Name;
33
use crate::utils::paths;
44
use crate::utils::usage::{is_unused, mutated_variables};
@@ -8,7 +8,7 @@ use crate::utils::{
88
multispan_sugg, snippet, snippet_opt, snippet_with_applicability, span_lint, span_lint_and_help,
99
span_lint_and_sugg, span_lint_and_then, SpanlessEq,
1010
};
11-
use crate::utils::{is_type_diagnostic_item, qpath_res, same_tys, sext, sugg};
11+
use crate::utils::{is_type_diagnostic_item, qpath_res, same_tys, sugg};
1212
use if_chain::if_chain;
1313
use rustc_ast::ast;
1414
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -270,30 +270,6 @@ declare_clippy_lint! {
270270
"collecting an iterator when collect is not needed"
271271
}
272272

273-
declare_clippy_lint! {
274-
/// **What it does:** Checks for loops over ranges `x..y` where both `x` and `y`
275-
/// are constant and `x` is greater or equal to `y`, unless the range is
276-
/// reversed or has a negative `.step_by(_)`.
277-
///
278-
/// **Why is it bad?** Such loops will either be skipped or loop until
279-
/// wrap-around (in debug code, this may `panic!()`). Both options are probably
280-
/// not intended.
281-
///
282-
/// **Known problems:** The lint cannot catch loops over dynamically defined
283-
/// ranges. Doing this would require simulating all possible inputs and code
284-
/// paths through the program, which would be complex and error-prone.
285-
///
286-
/// **Example:**
287-
/// ```ignore
288-
/// for x in 5..10 - 5 {
289-
/// ..
290-
/// } // oops, stray `-`
291-
/// ```
292-
pub REVERSE_RANGE_LOOP,
293-
correctness,
294-
"iteration over an empty range, such as `10..0` or `5..5`"
295-
}
296-
297273
declare_clippy_lint! {
298274
/// **What it does:** Checks `for` loops over slices with an explicit counter
299275
/// and suggests the use of `.enumerate()`.
@@ -463,7 +439,6 @@ declare_lint_pass!(Loops => [
463439
FOR_LOOP_OVER_OPTION,
464440
WHILE_LET_LOOP,
465441
NEEDLESS_COLLECT,
466-
REVERSE_RANGE_LOOP,
467442
EXPLICIT_COUNTER_LOOP,
468443
EMPTY_LOOP,
469444
WHILE_LET_ON_ITERATOR,
@@ -761,7 +736,6 @@ fn check_for_loop<'a, 'tcx>(
761736
expr: &'tcx Expr<'_>,
762737
) {
763738
check_for_loop_range(cx, pat, arg, body, expr);
764-
check_for_loop_reverse_range(cx, arg, expr);
765739
check_for_loop_arg(cx, pat, arg, expr);
766740
check_for_loop_explicit_counter(cx, pat, arg, body, expr);
767741
check_for_loop_over_map_kv(cx, pat, arg, body, expr);
@@ -1248,78 +1222,6 @@ fn is_end_eq_array_len<'tcx>(
12481222
false
12491223
}
12501224

1251-
fn check_for_loop_reverse_range<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, arg: &'tcx Expr<'_>, expr: &'tcx Expr<'_>) {
1252-
// if this for loop is iterating over a two-sided range...
1253-
if let Some(higher::Range {
1254-
start: Some(start),
1255-
end: Some(end),
1256-
limits,
1257-
}) = higher::range(cx, arg)
1258-
{
1259-
// ...and both sides are compile-time constant integers...
1260-
if let Some((start_idx, _)) = constant(cx, cx.tables, start) {
1261-
if let Some((end_idx, _)) = constant(cx, cx.tables, end) {
1262-
// ...and the start index is greater than the end index,
1263-
// this loop will never run. This is often confusing for developers
1264-
// who think that this will iterate from the larger value to the
1265-
// smaller value.
1266-
let ty = cx.tables.expr_ty(start);
1267-
let (sup, eq) = match (start_idx, end_idx) {
1268-
(Constant::Int(start_idx), Constant::Int(end_idx)) => (
1269-
match ty.kind {
1270-
ty::Int(ity) => sext(cx.tcx, start_idx, ity) > sext(cx.tcx, end_idx, ity),
1271-
ty::Uint(_) => start_idx > end_idx,
1272-
_ => false,
1273-
},
1274-
start_idx == end_idx,
1275-
),
1276-
_ => (false, false),
1277-
};
1278-
1279-
if sup {
1280-
let start_snippet = snippet(cx, start.span, "_");
1281-
let end_snippet = snippet(cx, end.span, "_");
1282-
let dots = if limits == ast::RangeLimits::Closed {
1283-
"..="
1284-
} else {
1285-
".."
1286-
};
1287-
1288-
span_lint_and_then(
1289-
cx,
1290-
REVERSE_RANGE_LOOP,
1291-
expr.span,
1292-
"this range is empty so this for loop will never run",
1293-
|diag| {
1294-
diag.span_suggestion(
1295-
arg.span,
1296-
"consider using the following if you are attempting to iterate over this \
1297-
range in reverse",
1298-
format!(
1299-
"({end}{dots}{start}).rev()",
1300-
end = end_snippet,
1301-
dots = dots,
1302-
start = start_snippet
1303-
),
1304-
Applicability::MaybeIncorrect,
1305-
);
1306-
},
1307-
);
1308-
} else if eq && limits != ast::RangeLimits::Closed {
1309-
// if they are equal, it's also problematic - this loop
1310-
// will never run.
1311-
span_lint(
1312-
cx,
1313-
REVERSE_RANGE_LOOP,
1314-
expr.span,
1315-
"this range is empty so this for loop will never run",
1316-
);
1317-
}
1318-
}
1319-
}
1320-
}
1321-
}
1322-
13231225
fn lint_iter_method(cx: &LateContext<'_, '_>, args: &[Expr<'_>], arg: &Expr<'_>, method_name: &str) {
13241226
let mut applicability = Applicability::MachineApplicable;
13251227
let object = snippet_with_applicability(cx, args[0].span, "_", &mut applicability);

Diff for: src/lintlist/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1922,11 +1922,11 @@ pub static ref ALL_LINTS: Vec<Lint> = vec![
19221922
module: "methods",
19231923
},
19241924
Lint {
1925-
name: "reverse_range_loop",
1925+
name: "reversed_empty_ranges",
19261926
group: "correctness",
1927-
desc: "iteration over an empty range, such as `10..0` or `5..5`",
1927+
desc: "reversing the limits of range expressions, resulting in empty ranges",
19281928
deprecation: None,
1929-
module: "loops",
1929+
module: "ranges",
19301930
},
19311931
Lint {
19321932
name: "same_functions_in_if_condition",

Diff for: tests/ui/for_loop_fixable.fixed

-54
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ impl Unrelated {
2121
clippy::explicit_iter_loop,
2222
clippy::explicit_into_iter_loop,
2323
clippy::iter_next_loop,
24-
clippy::reverse_range_loop,
2524
clippy::for_kv_map
2625
)]
2726
#[allow(
@@ -32,61 +31,8 @@ impl Unrelated {
3231
)]
3332
#[allow(clippy::many_single_char_names, unused_variables)]
3433
fn main() {
35-
const MAX_LEN: usize = 42;
3634
let mut vec = vec![1, 2, 3, 4];
3735

38-
for i in (0..10).rev() {
39-
println!("{}", i);
40-
}
41-
42-
for i in (0..=10).rev() {
43-
println!("{}", i);
44-
}
45-
46-
for i in (0..MAX_LEN).rev() {
47-
println!("{}", i);
48-
}
49-
50-
for i in 5..=5 {
51-
// not an error, this is the range with only one element “5”
52-
println!("{}", i);
53-
}
54-
55-
for i in 0..10 {
56-
// not an error, the start index is less than the end index
57-
println!("{}", i);
58-
}
59-
60-
for i in -10..0 {
61-
// not an error
62-
println!("{}", i);
63-
}
64-
65-
for i in (10..0).map(|x| x * 2) {
66-
// not an error, it can't be known what arbitrary methods do to a range
67-
println!("{}", i);
68-
}
69-
70-
// testing that the empty range lint folds constants
71-
for i in (5 + 4..10).rev() {
72-
println!("{}", i);
73-
}
74-
75-
for i in ((3 - 1)..(5 + 2)).rev() {
76-
println!("{}", i);
77-
}
78-
79-
for i in (2 * 2)..(2 * 3) {
80-
// no error, 4..6 is fine
81-
println!("{}", i);
82-
}
83-
84-
let x = 42;
85-
for i in x..10 {
86-
// no error, not constant-foldable
87-
println!("{}", i);
88-
}
89-
9036
// See #601
9137
for i in 0..10 {
9238
// no error, id_col does not exist outside the loop

Diff for: tests/ui/for_loop_fixable.rs

-54
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ impl Unrelated {
2121
clippy::explicit_iter_loop,
2222
clippy::explicit_into_iter_loop,
2323
clippy::iter_next_loop,
24-
clippy::reverse_range_loop,
2524
clippy::for_kv_map
2625
)]
2726
#[allow(
@@ -32,61 +31,8 @@ impl Unrelated {
3231
)]
3332
#[allow(clippy::many_single_char_names, unused_variables)]
3433
fn main() {
35-
const MAX_LEN: usize = 42;
3634
let mut vec = vec![1, 2, 3, 4];
3735

38-
for i in 10..0 {
39-
println!("{}", i);
40-
}
41-
42-
for i in 10..=0 {
43-
println!("{}", i);
44-
}
45-
46-
for i in MAX_LEN..0 {
47-
println!("{}", i);
48-
}
49-
50-
for i in 5..=5 {
51-
// not an error, this is the range with only one element “5”
52-
println!("{}", i);
53-
}
54-
55-
for i in 0..10 {
56-
// not an error, the start index is less than the end index
57-
println!("{}", i);
58-
}
59-
60-
for i in -10..0 {
61-
// not an error
62-
println!("{}", i);
63-
}
64-
65-
for i in (10..0).map(|x| x * 2) {
66-
// not an error, it can't be known what arbitrary methods do to a range
67-
println!("{}", i);
68-
}
69-
70-
// testing that the empty range lint folds constants
71-
for i in 10..5 + 4 {
72-
println!("{}", i);
73-
}
74-
75-
for i in (5 + 2)..(3 - 1) {
76-
println!("{}", i);
77-
}
78-
79-
for i in (2 * 2)..(2 * 3) {
80-
// no error, 4..6 is fine
81-
println!("{}", i);
82-
}
83-
84-
let x = 42;
85-
for i in x..10 {
86-
// no error, not constant-foldable
87-
println!("{}", i);
88-
}
89-
9036
// See #601
9137
for i in 0..10 {
9238
// no error, id_col does not exist outside the loop

0 commit comments

Comments
 (0)