@@ -27,6 +27,7 @@ use crate::rustc::ty::subst::Subst;
27
27
use crate :: rustc_errors:: Applicability ;
28
28
use crate :: rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
29
29
use std:: iter:: { once, Iterator } ;
30
+ use std:: mem;
30
31
use crate :: syntax:: ast;
31
32
use crate :: syntax:: source_map:: Span ;
32
33
use crate :: syntax_pos:: BytePos ;
@@ -1082,16 +1083,35 @@ fn check_for_loop_range<'a, 'tcx>(
1082
1083
format ! ( ".skip({})" , snippet( cx, start. span, ".." ) )
1083
1084
} ;
1084
1085
1086
+ let mut end_is_start_plus_val = false ;
1087
+
1085
1088
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
+
1086
1106
if is_len_call ( end, indexed) {
1087
1107
String :: new ( )
1088
1108
} else {
1089
1109
match limits {
1090
1110
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 )
1093
1113
} ,
1094
- ast:: RangeLimits :: HalfOpen => format ! ( ".take({})" , snippet( cx, end . span, ".." ) ) ,
1114
+ ast:: RangeLimits :: HalfOpen => format ! ( ".take({})" , snippet( cx, take_expr . span, ".." ) ) ,
1095
1115
}
1096
1116
}
1097
1117
} else {
@@ -1104,6 +1124,14 @@ fn check_for_loop_range<'a, 'tcx>(
1104
1124
( "" , "iter" )
1105
1125
} ;
1106
1126
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
+
1107
1135
if visitor. nonindex {
1108
1136
span_lint_and_then (
1109
1137
cx,
@@ -1116,16 +1144,16 @@ fn check_for_loop_range<'a, 'tcx>(
1116
1144
"consider using an iterator" . to_string ( ) ,
1117
1145
vec ! [
1118
1146
( 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 ) ) ,
1120
1148
] ,
1121
1149
) ;
1122
1150
} ,
1123
1151
) ;
1124
1152
} else {
1125
- let repl = if starts_at_zero && take . is_empty ( ) {
1153
+ let repl = if starts_at_zero && take_is_empty {
1126
1154
format ! ( "&{}{}" , ref_mut, indexed)
1127
1155
} else {
1128
- format ! ( "{}.{}(){}{}" , indexed, method, take , skip )
1156
+ format ! ( "{}.{}(){}{}" , indexed, method, method_1 , method_2 )
1129
1157
} ;
1130
1158
1131
1159
span_lint_and_then (
0 commit comments