Add suggestions to EXPLICIT_[INTO_]ITER_LOOP
Also reduces the highlighted span to the expr containing the `.[into_]iter()` call (so the suggestion is probably applicable by rustfix.) Fixes #1484
This commit is contained in:
@@ -588,28 +588,38 @@ fn check_for_loop_arg(cx: &LateContext, pat: &Pat, arg: &Expr, expr: &Expr) {
|
|||||||
if &*method_name.as_str() == "iter" || &*method_name.as_str() == "iter_mut" {
|
if &*method_name.as_str() == "iter" || &*method_name.as_str() == "iter_mut" {
|
||||||
if is_ref_iterable_type(cx, &args[0]) {
|
if is_ref_iterable_type(cx, &args[0]) {
|
||||||
let object = snippet(cx, args[0].span, "_");
|
let object = snippet(cx, args[0].span, "_");
|
||||||
span_lint(cx,
|
let suggestion = format!("&{}{}",
|
||||||
EXPLICIT_ITER_LOOP,
|
if &*method_name.as_str() == "iter_mut" {
|
||||||
expr.span,
|
"mut "
|
||||||
&format!("it is more idiomatic to loop over `&{}{}` instead of `{}.{}()`",
|
} else {
|
||||||
if &*method_name.as_str() == "iter_mut" {
|
""
|
||||||
"mut "
|
},
|
||||||
} else {
|
object);
|
||||||
""
|
span_lint_and_then(cx,
|
||||||
},
|
EXPLICIT_ITER_LOOP,
|
||||||
object,
|
arg.span,
|
||||||
object,
|
&format!("it is more idiomatic to loop over `{}` instead of `{}.{}()`",
|
||||||
method_name));
|
suggestion,
|
||||||
|
object,
|
||||||
|
method_name),
|
||||||
|
|db| {
|
||||||
|
db.span_suggestion(arg.span, "to write this more concisely, try looping over", suggestion);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else if &*method_name.as_str() == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) {
|
} else if &*method_name.as_str() == "into_iter" && match_trait_method(cx, arg, &paths::INTO_ITERATOR) {
|
||||||
let object = snippet(cx, args[0].span, "_");
|
let object = snippet(cx, args[0].span, "_");
|
||||||
span_lint(cx,
|
span_lint_and_then(cx,
|
||||||
EXPLICIT_INTO_ITER_LOOP,
|
EXPLICIT_INTO_ITER_LOOP,
|
||||||
expr.span,
|
arg.span,
|
||||||
&format!("it is more idiomatic to loop over `{}` instead of `{}.{}()`",
|
&format!("it is more idiomatic to loop over `{}` instead of `{}.{}()`",
|
||||||
object,
|
object,
|
||||||
object,
|
object,
|
||||||
method_name));
|
method_name),
|
||||||
|
|db| {
|
||||||
|
db.span_suggestion(arg.span,
|
||||||
|
"to write this more concisely, try looping over",
|
||||||
|
object.to_string());
|
||||||
|
});
|
||||||
|
|
||||||
} else if &*method_name.as_str() == "next" && match_trait_method(cx, arg, &paths::ITERATOR) {
|
} else if &*method_name.as_str() == "next" && match_trait_method(cx, arg, &paths::ITERATOR) {
|
||||||
span_lint(cx,
|
span_lint(cx,
|
||||||
|
|||||||
@@ -286,39 +286,86 @@ fn main() {
|
|||||||
id_col[i] = 1f64;
|
id_col[i] = 1f64;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// This is fine.
|
||||||
for i in (10..0).map(|x| x * 2) {
|
for i in (10..0).map(|x| x * 2) {
|
||||||
println!("{}", i);
|
println!("{}", i);
|
||||||
}*/
|
}
|
||||||
|
|
||||||
for _v in vec.iter() { } //~ERROR it is more idiomatic to loop over `&vec`
|
for _v in vec.iter() { }
|
||||||
for _v in vec.iter_mut() { } //~ERROR it is more idiomatic to loop over `&mut vec`
|
//~^ ERROR it is more idiomatic to loop over `&vec`
|
||||||
|
//~| HELP to write this more concisely, try looping over
|
||||||
|
//~| SUGGESTION &vec
|
||||||
|
|
||||||
|
for _v in vec.iter_mut() { }
|
||||||
|
//~^ ERROR it is more idiomatic to loop over `&mut vec`
|
||||||
|
//~| HELP to write this more concisely, try looping over
|
||||||
|
//~| SUGGESTION vec
|
||||||
|
|
||||||
let out_vec = vec![1,2,3];
|
let out_vec = vec![1,2,3];
|
||||||
for _v in out_vec.into_iter() { } //~ERROR it is more idiomatic to loop over `out_vec` instead of `out_vec.into_iter()`
|
for _v in out_vec.into_iter() { }
|
||||||
|
//~^ ERROR it is more idiomatic to loop over `out_vec` instead of `out_vec.into_iter()`
|
||||||
|
//~| HELP to write this more concisely, try looping over
|
||||||
|
//~| SUGGESTION out_vec
|
||||||
|
|
||||||
for _v in &vec { } // these are fine
|
for _v in &vec { } // these are fine
|
||||||
for _v in &mut vec { } // these are fine
|
for _v in &mut vec { } // these are fine
|
||||||
|
|
||||||
for _v in [1, 2, 3].iter() { } //~ERROR it is more idiomatic to loop over `&[
|
for _v in [1, 2, 3].iter() { }
|
||||||
|
//~^ ERROR it is more idiomatic to loop over `&[
|
||||||
|
//~| HELP to write this more concisely, try looping over
|
||||||
|
//~| SUGGESTION &[1, 2, 3]
|
||||||
|
|
||||||
for _v in (&mut [1, 2, 3]).iter() { } // no error
|
for _v in (&mut [1, 2, 3]).iter() { } // no error
|
||||||
for _v in [0; 32].iter() {} //~ERROR it is more idiomatic to loop over `&[
|
|
||||||
|
for _v in [0; 32].iter() {}
|
||||||
|
//~^ ERROR it is more idiomatic to loop over `&[
|
||||||
|
//~| HELP to write this more concisely, try looping over
|
||||||
|
//~| SUGGESTION &[0; 32]
|
||||||
|
|
||||||
for _v in [0; 33].iter() {} // no error
|
for _v in [0; 33].iter() {} // no error
|
||||||
|
|
||||||
let ll: LinkedList<()> = LinkedList::new();
|
let ll: LinkedList<()> = LinkedList::new();
|
||||||
for _v in ll.iter() { } //~ERROR it is more idiomatic to loop over `&ll`
|
for _v in ll.iter() { }
|
||||||
|
//~^ ERROR it is more idiomatic to loop over `&ll`
|
||||||
|
//~| HELP to write this more concisely, try looping over
|
||||||
|
//~| SUGGESTION &ll
|
||||||
|
|
||||||
let vd: VecDeque<()> = VecDeque::new();
|
let vd: VecDeque<()> = VecDeque::new();
|
||||||
for _v in vd.iter() { } //~ERROR it is more idiomatic to loop over `&vd`
|
for _v in vd.iter() { }
|
||||||
|
//~^ ERROR it is more idiomatic to loop over `&vd`
|
||||||
|
//~| HELP to write this more concisely, try looping over
|
||||||
|
//~| SUGGESTION &vd
|
||||||
|
|
||||||
let bh: BinaryHeap<()> = BinaryHeap::new();
|
let bh: BinaryHeap<()> = BinaryHeap::new();
|
||||||
for _v in bh.iter() { } //~ERROR it is more idiomatic to loop over `&bh`
|
for _v in bh.iter() { }
|
||||||
|
//~^ ERROR it is more idiomatic to loop over `&bh`
|
||||||
|
//~| HELP to write this more concisely, try looping over
|
||||||
|
//~| SUGGESTION &bh
|
||||||
|
|
||||||
let hm: HashMap<(), ()> = HashMap::new();
|
let hm: HashMap<(), ()> = HashMap::new();
|
||||||
for _v in hm.iter() { } //~ERROR it is more idiomatic to loop over `&hm`
|
for _v in hm.iter() { }
|
||||||
|
//~^ ERROR it is more idiomatic to loop over `&hm`
|
||||||
|
//~| HELP to write this more concisely, try looping over
|
||||||
|
//~| SUGGESTION &hm
|
||||||
|
|
||||||
let bt: BTreeMap<(), ()> = BTreeMap::new();
|
let bt: BTreeMap<(), ()> = BTreeMap::new();
|
||||||
for _v in bt.iter() { } //~ERROR it is more idiomatic to loop over `&bt`
|
for _v in bt.iter() { }
|
||||||
|
//~^ ERROR it is more idiomatic to loop over `&bt`
|
||||||
|
//~| HELP to write this more concisely, try looping over
|
||||||
|
//~| SUGGESTION &bt
|
||||||
|
|
||||||
let hs: HashSet<()> = HashSet::new();
|
let hs: HashSet<()> = HashSet::new();
|
||||||
for _v in hs.iter() { } //~ERROR it is more idiomatic to loop over `&hs`
|
for _v in hs.iter() { }
|
||||||
|
//~^ ERROR it is more idiomatic to loop over `&hs`
|
||||||
|
//~| HELP to write this more concisely, try looping over
|
||||||
|
//~| SUGGESTION &hs
|
||||||
|
|
||||||
let bs: BTreeSet<()> = BTreeSet::new();
|
let bs: BTreeSet<()> = BTreeSet::new();
|
||||||
for _v in bs.iter() { } //~ERROR it is more idiomatic to loop over `&bs`
|
for _v in bs.iter() { }
|
||||||
|
//~^ ERROR it is more idiomatic to loop over `&bs`
|
||||||
|
//~| HELP to write this more concisely, try looping over
|
||||||
|
//~| SUGGESTION &bs
|
||||||
|
|
||||||
|
|
||||||
for _v in vec.iter().next() { } //~ERROR you are iterating over `Iterator::next()`
|
for _v in vec.iter().next() { } //~ERROR you are iterating over `Iterator::next()`
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user