@@ -27,6 +27,7 @@ use crate::rustc::ty::subst::Subst;
2727use crate :: rustc_errors:: Applicability ;
2828use crate :: rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
2929use std:: iter:: { once, Iterator } ;
30+ use std:: mem;
3031use crate :: syntax:: ast;
3132use crate :: syntax:: source_map:: Span ;
3233use crate :: syntax_pos:: BytePos ;
@@ -1082,16 +1083,35 @@ fn check_for_loop_range<'a, 'tcx>(
10821083 format ! ( ".skip({})" , snippet( cx, start. span, ".." ) )
10831084 } ;
10841085
1086+ let mut end_is_start_plus_val = false ;
1087+
10851088 let take = if let Some ( end) = * end {
1089+ let mut take_expr = end;
1090+
1091+ if let ExprKind :: Binary ( ref op, ref left, ref right) = end. node {
1092+ if let BinOpKind :: Add = op. node {
1093+ let start_equal_left = SpanlessEq :: new ( cx) . eq_expr ( start, left) ;
1094+ let start_equal_right = SpanlessEq :: new ( cx) . eq_expr ( start, right) ;
1095+
1096+ if start_equal_left {
1097+ take_expr = right;
1098+ } else if start_equal_right {
1099+ take_expr = left;
1100+ }
1101+
1102+ end_is_start_plus_val = start_equal_left | start_equal_right;
1103+ }
1104+ }
1105+
10861106 if is_len_call ( end, indexed) {
10871107 String :: new ( )
10881108 } else {
10891109 match limits {
10901110 ast:: RangeLimits :: Closed => {
1091- let end = sugg:: Sugg :: hir ( cx, end , "<count>" ) ;
1092- format ! ( ".take({})" , end + sugg:: ONE )
1111+ let take_expr = sugg:: Sugg :: hir ( cx, take_expr , "<count>" ) ;
1112+ format ! ( ".take({})" , take_expr + sugg:: ONE )
10931113 } ,
1094- ast:: RangeLimits :: HalfOpen => format ! ( ".take({})" , snippet( cx, end . span, ".." ) ) ,
1114+ ast:: RangeLimits :: HalfOpen => format ! ( ".take({})" , snippet( cx, take_expr . span, ".." ) ) ,
10951115 }
10961116 }
10971117 } else {
@@ -1104,6 +1124,14 @@ fn check_for_loop_range<'a, 'tcx>(
11041124 ( "" , "iter" )
11051125 } ;
11061126
1127+ let take_is_empty = take. is_empty ( ) ;
1128+ let mut method_1 = take;
1129+ let mut method_2 = skip;
1130+
1131+ if end_is_start_plus_val {
1132+ mem:: swap ( & mut method_1, & mut method_2) ;
1133+ }
1134+
11071135 if visitor. nonindex {
11081136 span_lint_and_then (
11091137 cx,
@@ -1116,16 +1144,16 @@ fn check_for_loop_range<'a, 'tcx>(
11161144 "consider using an iterator" . to_string ( ) ,
11171145 vec ! [
11181146 ( pat. span, format!( "({}, <item>)" , ident. name) ) ,
1119- ( arg. span, format!( "{}.{}().enumerate(){}{}" , indexed, method, take , skip ) ) ,
1147+ ( arg. span, format!( "{}.{}().enumerate(){}{}" , indexed, method, method_1 , method_2 ) ) ,
11201148 ] ,
11211149 ) ;
11221150 } ,
11231151 ) ;
11241152 } else {
1125- let repl = if starts_at_zero && take . is_empty ( ) {
1153+ let repl = if starts_at_zero && take_is_empty {
11261154 format ! ( "&{}{}" , ref_mut, indexed)
11271155 } else {
1128- format ! ( "{}.{}(){}{}" , indexed, method, take , skip )
1156+ format ! ( "{}.{}(){}{}" , indexed, method, method_1 , method_2 )
11291157 } ;
11301158
11311159 span_lint_and_then (
0 commit comments