diff --git a/src/loops.rs b/src/loops.rs index f6247dd8419..33401dc67e1 100644 --- a/src/loops.rs +++ b/src/loops.rs @@ -4,7 +4,7 @@ use syntax::visit::{Visitor, walk_expr}; use rustc::middle::ty; use std::collections::HashSet; -use utils::{snippet, span_lint, get_parent_expr, match_trait_method, match_type, walk_ptrs_ty, +use utils::{snippet, span_lint, get_parent_expr, match_trait_method, match_type, in_external_macro, expr_block, span_help_and_lint}; use utils::{VEC_PATH, LL_PATH}; @@ -191,7 +191,9 @@ impl<'v, 't> Visitor<'v> for VarVisitor<'v, 't> { /// Return true if the type of expr is one that provides IntoIterator impls /// for &T and &mut T, such as Vec. fn is_ref_iterable_type(cx: &Context, e: &Expr) -> bool { - let ty = walk_ptrs_ty(cx.tcx.expr_ty(e)); + // no walk_ptrs_ty: calling iter() on a reference can make sense because it + // will allow further borrows afterwards + let ty = cx.tcx.expr_ty(e); is_array(ty) || match_type(cx, ty, &VEC_PATH) || match_type(cx, ty, &LL_PATH) || diff --git a/tests/compile-fail/for_loop.rs b/tests/compile-fail/for_loop.rs index 66838651356..f2540bfd595 100755 --- a/tests/compile-fail/for_loop.rs +++ b/tests/compile-fail/for_loop.rs @@ -37,6 +37,7 @@ fn main() { 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 (&mut [1, 2, 3]).iter() { } // no error let ll: LinkedList<()> = LinkedList::new(); for _v in ll.iter() { } //~ERROR it is more idiomatic to loop over `&ll` let vd: VecDeque<()> = VecDeque::new();