Skip to content

Commit f6c9490

Browse files
committed
Fix wrong suggestion with ... and for loops
1 parent dbf6dc6 commit f6c9490

File tree

2 files changed

+19
-11
lines changed

2 files changed

+19
-11
lines changed

clippy_lints/src/loops.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ use rustc::middle::region::CodeExtent;
99
use rustc::ty;
1010
use rustc_const_eval::EvalHint::ExprTypeChecked;
1111
use rustc_const_eval::eval_const_expr_partial;
12-
use std::borrow::Cow;
1312
use std::collections::HashMap;
1413
use syntax::ast;
14+
use utils::sugg;
1515

1616
use utils::{snippet, span_lint, get_parent_expr, match_trait_method, match_type, multispan_sugg, in_external_macro,
1717
span_help_and_lint, is_integer_literal, get_enclosing_block, span_lint_and_then, higher,
@@ -332,7 +332,7 @@ fn check_for_loop(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Expr, expr: &E
332332
/// Check for looping over a range and then indexing a sequence with it.
333333
/// The iteratee must be a range literal.
334334
fn check_for_loop_range(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Expr, expr: &Expr) {
335-
if let Some(higher::Range { start: Some(ref start), ref end, .. }) = higher::range(arg) {
335+
if let Some(higher::Range { start: Some(ref start), ref end, limits }) = higher::range(arg) {
336336
// the var must be a single name
337337
if let PatKind::Binding(_, ref ident, _) = pat.node {
338338
let mut visitor = VarVisitor {
@@ -360,20 +360,28 @@ fn check_for_loop_range(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Expr, ex
360360

361361
let starts_at_zero = is_integer_literal(start, 0);
362362

363-
let skip: Cow<_> = if starts_at_zero {
364-
"".into()
363+
let skip = if starts_at_zero {
364+
"".to_owned()
365365
} else {
366-
format!(".skip({})", snippet(cx, start.span, "..")).into()
366+
format!(".skip({})", snippet(cx, start.span, ".."))
367367
};
368368

369-
let take: Cow<_> = if let Some(ref end) = *end {
369+
let take = if let Some(ref end) = *end {
370370
if is_len_call(end, &indexed) {
371-
"".into()
371+
"".to_owned()
372372
} else {
373-
format!(".take({})", snippet(cx, end.span, "..")).into()
373+
match limits {
374+
ast::RangeLimits::Closed => {
375+
let end = sugg::Sugg::hir(cx, end, "<count>");
376+
format!(".take({})", end + sugg::ONE)
377+
}
378+
ast::RangeLimits::HalfOpen => {
379+
format!(".take({})", snippet(cx, end.span, ".."))
380+
}
381+
}
374382
}
375383
} else {
376-
"".into()
384+
"".to_owned()
377385
};
378386

379387
if visitor.nonindex {

tests/compile-fail/for_loop.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ fn main() {
165165
//~^ ERROR `i` is only used to index `vec`
166166
//~| HELP consider
167167
//~| HELP consider
168-
//~| SUGGESTION for <item> in vec.iter().take(MAX_LEN) {
168+
//~| SUGGESTION for <item> in vec.iter().take(MAX_LEN + 1) {
169169
println!("{}", vec[i]);
170170
}
171171

@@ -181,7 +181,7 @@ fn main() {
181181
//~^ ERROR `i` is only used to index `vec`
182182
//~| HELP consider
183183
//~| HELP consider
184-
//~| SUGGESTION for <item> in vec.iter().take(10).skip(5) {
184+
//~| SUGGESTION for <item> in vec.iter().take(10 + 1).skip(5) {
185185
println!("{}", vec[i]);
186186
}
187187

0 commit comments

Comments
 (0)