Fix check of immutable condition in closure

This commit is contained in:
flip1995 2018-03-25 17:23:31 +02:00
parent b01b0083ba
commit d458f22d89
No known key found for this signature in database
GPG key ID: 852B722799AB5978
2 changed files with 30 additions and 1 deletions

View file

@ -2150,8 +2150,20 @@ fn check_infinite_loop<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, cond: &'tcx Expr, b
return;
}
if mut_var_visitor.ids.is_empty() {
span_lint(
cx,
WHILE_IMMUTABLE_CONDITION,
cond.span,
"all variables in condition are immutable. This either leads to an infinite or to a never running loop.",
);
return;
}
let mut delegate = MutVarsDelegate {
used_mutably: mut_var_visitor.ids,
skip: false,
};
let def_id = def_id::DefId::local(block.hir_id.owner);
let region_scope_tree = &cx.tcx.region_scope_tree(def_id);
@ -2194,7 +2206,10 @@ impl<'a, 'tcx> VarCollectorVisitor<'a, 'tcx> {
impl<'a, 'tcx> Visitor<'tcx> for VarCollectorVisitor<'a, 'tcx> {
fn visit_expr(&mut self, ex: &'tcx Expr) {
match ex.node {
ExprPath(_) => self.insert_def_id(ex),
ExprPath(_) => if let Some(node_id) = check_for_mutability(self.cx, ex) {
self.ids.insert(node_id, false);
},
// If there is any fuction/method call… we just stop analysis
ExprCall(..) | ExprMethodCall(..) => self.skip = true,
@ -2211,6 +2226,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarCollectorVisitor<'a, 'tcx> {
struct MutVarsDelegate {
used_mutably: HashMap<NodeId, bool>,
skip: bool,
}
impl<'tcx> MutVarsDelegate {
@ -2220,6 +2236,7 @@ impl<'tcx> MutVarsDelegate {
if let Some(used) = self.used_mutably.get_mut(&id) {
*used = true;
},
Categorization::Upvar(_) => skip = true,
Categorization::Deref(ref cmt, _) => self.update(&cmt.cat, sp),
_ => {}
}

View file

@ -1,9 +1,13 @@
fn fn_val(i: i32) -> i32 { unimplemented!() }
fn fn_constref(i: &i32) -> i32 { unimplemented!() }
fn fn_mutref(i: &mut i32) { unimplemented!() }
fn fooi() -> i32 { unimplemented!() }
fn foob() -> bool { unimplemented!() }
#[allow(many_single_char_names)]
fn immutable_condition() {
// Should warn when all vars mentionned are immutable
let y = 0;
@ -43,6 +47,14 @@ fn immutable_condition() {
println!("OK - Fn call results may vary");
}
let mut a = 0;
let mut c = move || {
while a < 5 {
a += 1;
println!("OK - a is mutable");
}
};
c();
}
fn unused_var() {