Fix FP with for loops and shadowed loop variable

This commit is contained in:
mcarton 2016-07-10 14:05:57 +02:00
parent ad1cd99054
commit 3a7402a6d2
No known key found for this signature in database
GPG Key ID: 5E427C794CBA45E8
2 changed files with 10 additions and 3 deletions

View File

@ -1,6 +1,7 @@
use reexport::*; use reexport::*;
use rustc::hir::*; use rustc::hir::*;
use rustc::hir::def::Def; use rustc::hir::def::Def;
use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::{Visitor, walk_expr, walk_block, walk_decl}; use rustc::hir::intravisit::{Visitor, walk_expr, walk_block, walk_decl};
use rustc::hir::map::Node::NodeBlock; use rustc::hir::map::Node::NodeBlock;
use rustc::lint::*; use rustc::lint::*;
@ -337,7 +338,7 @@ fn check_for_loop_range(cx: &LateContext, pat: &Pat, arg: &Expr, body: &Expr, ex
if let PatKind::Binding(_, ref ident, _) = pat.node { if let PatKind::Binding(_, ref ident, _) = pat.node {
let mut visitor = VarVisitor { let mut visitor = VarVisitor {
cx: cx, cx: cx,
var: ident.node, var: cx.tcx.expect_def(pat.id).def_id(),
indexed: HashMap::new(), indexed: HashMap::new(),
nonindex: false, nonindex: false,
}; };
@ -667,7 +668,7 @@ impl<'a> Visitor<'a> for UsedVisitor {
struct VarVisitor<'v, 't: 'v> { struct VarVisitor<'v, 't: 'v> {
cx: &'v LateContext<'v, 't>, // context reference cx: &'v LateContext<'v, 't>, // context reference
var: Name, // var name to look for as index var: DefId, // var name to look for as index
indexed: HashMap<Name, Option<CodeExtent>>, // indexed variables, the extent is None for global indexed: HashMap<Name, Option<CodeExtent>>, // indexed variables, the extent is None for global
nonindex: bool, // has the var been used otherwise? nonindex: bool, // has the var been used otherwise?
} }
@ -675,7 +676,7 @@ struct VarVisitor<'v, 't: 'v> {
impl<'v, 't> Visitor<'v> for VarVisitor<'v, 't> { impl<'v, 't> Visitor<'v> for VarVisitor<'v, 't> {
fn visit_expr(&mut self, expr: &'v Expr) { fn visit_expr(&mut self, expr: &'v Expr) {
if let ExprPath(None, ref path) = expr.node { if let ExprPath(None, ref path) = expr.node {
if path.segments.len() == 1 && path.segments[0].name == self.var { if path.segments.len() == 1 && self.cx.tcx.expect_def(expr.id).def_id() == self.var {
// we are referencing our variable! now check if it's as an index // we are referencing our variable! now check if it's as an index
if_let_chain! {[ if_let_chain! {[
let Some(parexpr) = get_parent_expr(self.cx, expr), let Some(parexpr) = get_parent_expr(self.cx, expr),

View File

@ -104,6 +104,12 @@ fn main() {
println!("{}", vec[i]); println!("{}", vec[i]);
} }
for i in 0..vec.len() {
//~^ WARNING unused variable
let i = 42; // make a different `i`
println!("{}", vec[i]); // ok, not the `i` of the for-loop
}
for i in 0..vec.len() { let _ = vec[i]; } for i in 0..vec.len() { let _ = vec[i]; }
//~^ ERROR `i` is only used to index `vec` //~^ ERROR `i` is only used to index `vec`
//~| HELP consider //~| HELP consider