1- use crate :: consts:: { constant, Constant } ;
1+ use crate :: consts:: constant;
22use crate :: reexport:: Name ;
33use crate :: utils:: paths;
44use 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} ;
1212use if_chain:: if_chain;
1313use rustc_ast:: ast;
1414use 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-
297273declare_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-
13231225fn 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) ;
0 commit comments