]> git.lizzy.rs Git - rust.git/commitdiff
Fix wrong suggestion with `...` and for loops
authormcarton <cartonmartin+git@gmail.com>
Fri, 1 Jul 2016 17:31:14 +0000 (19:31 +0200)
committermcarton <cartonmartin+git@gmail.com>
Fri, 1 Jul 2016 17:31:14 +0000 (19:31 +0200)
clippy_lints/src/loops.rs
tests/compile-fail/for_loop.rs

index 0f9d030c2f285b373d8256e823aa40370e2ffb7c..2aa0332a8241f8af4db846b8c9600671eb8b2dd1 100644 (file)
@@ -9,9 +9,9 @@
 use rustc::ty;
 use rustc_const_eval::EvalHint::ExprTypeChecked;
 use rustc_const_eval::eval_const_expr_partial;
-use std::borrow::Cow;
 use std::collections::HashMap;
 use syntax::ast;
+use utils::sugg;
 
 use utils::{snippet, span_lint, get_parent_expr, match_trait_method, match_type, multispan_sugg, in_external_macro,
             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
 /// Check for looping over a range and then indexing a sequence with it.
 /// The iteratee must be a range literal.
 fn check_for_loop_range(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Expr, expr: &Expr) {
-    if let Some(higher::Range { start: Some(ref start), ref end, .. }) = higher::range(arg) {
+    if let Some(higher::Range { start: Some(ref start), ref end, limits }) = higher::range(arg) {
         // the var must be a single name
         if let PatKind::Binding(_, ref ident, _) = pat.node {
             let mut visitor = VarVisitor {
@@ -360,20 +360,28 @@ fn check_for_loop_range(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Expr, ex
 
                 let starts_at_zero = is_integer_literal(start, 0);
 
-                let skip: Cow<_> = if starts_at_zero {
-                    "".into()
+                let skip = if starts_at_zero {
+                    "".to_owned()
                 } else {
-                    format!(".skip({})", snippet(cx, start.span, "..")).into()
+                    format!(".skip({})", snippet(cx, start.span, ".."))
                 };
 
-                let take: Cow<_> = if let Some(ref end) = *end {
+                let take = if let Some(ref end) = *end {
                     if is_len_call(end, &indexed) {
-                        "".into()
+                        "".to_owned()
                     } else {
-                        format!(".take({})", snippet(cx, end.span, "..")).into()
+                        match limits {
+                            ast::RangeLimits::Closed => {
+                                let end = sugg::Sugg::hir(cx, end, "<count>");
+                                format!(".take({})", end + sugg::ONE)
+                            }
+                            ast::RangeLimits::HalfOpen => {
+                                format!(".take({})", snippet(cx, end.span, ".."))
+                            }
+                        }
                     }
                 } else {
-                    "".into()
+                    "".to_owned()
                 };
 
                 if visitor.nonindex {
index 6028c5c0f3a84ddde5c98c3f84dfdd1773aca3bc..1ef8eacd1d9491c16229ae00ea192a433beb38f0 100644 (file)
@@ -165,7 +165,7 @@ fn main() {
         //~^ ERROR `i` is only used to index `vec`
         //~| HELP consider
         //~| HELP consider
-        //~| SUGGESTION for <item> in vec.iter().take(MAX_LEN) {
+        //~| SUGGESTION for <item> in vec.iter().take(MAX_LEN + 1) {
         println!("{}", vec[i]);
     }
 
@@ -181,7 +181,7 @@ fn main() {
         //~^ ERROR `i` is only used to index `vec`
         //~| HELP consider
         //~| HELP consider
-        //~| SUGGESTION for <item> in vec.iter().take(10).skip(5) {
+        //~| SUGGESTION for <item> in vec.iter().take(10 + 1).skip(5) {
         println!("{}", vec[i]);
     }