From a18d9842ed94ecca3e7161945bb2f749d98d18ee Mon Sep 17 00:00:00 2001 From: Ariel Ben-Yehuda Date: Thu, 18 Jun 2015 01:02:58 +0300 Subject: [PATCH] Make the unused_mut lint smarter with respect to locals. Fixes #26332 --- src/libcore/iter.rs | 4 +-- src/libfmt_macros/lib.rs | 2 +- src/librustc/middle/infer/error_reporting.rs | 2 +- src/librustc_borrowck/borrowck/check_loans.rs | 25 ++++++------------- src/librustc_trans/save/dump_csv.rs | 2 +- src/libsyntax/parse/lexer/mod.rs | 2 +- .../compile-fail/lint-unused-mut-variables.rs | 9 +++++++ 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 3026f91e853ee..4c8511eb1902c 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -2655,8 +2655,8 @@ macro_rules! step_impl_signed { #[allow(trivial_numeric_casts)] fn steps_between(start: &$t, end: &$t, by: &$t) -> Option { if *by == 0 { return None; } - let mut diff: usize; - let mut by_u: usize; + let diff: usize; + let by_u: usize; if *by > 0 { if *start >= *end { return Some(0); diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs index c2b28bd134d47..7ca89cfd0c9cc 100644 --- a/src/libfmt_macros/lib.rs +++ b/src/libfmt_macros/lib.rs @@ -399,7 +399,7 @@ impl<'a> Parser<'a> { } Some(..) | None => { return &self.input[..0]; } }; - let mut end; + let end; loop { match self.cur.clone().next() { Some((_, c)) if c.is_xid_continue() => { diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 17075c0cba6ca..6d5b47d8ed980 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -1854,7 +1854,7 @@ impl LifeGiver { } fn give_lifetime(&self) -> ast::Lifetime { - let mut lifetime; + let lifetime; loop { let mut s = String::from("'"); s.push_str(&num_to_string(self.counter.get())); diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index f06dc105d9cc1..237add6ff860e 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -182,7 +182,7 @@ impl<'a, 'tcx> euv::Delegate<'tcx> for CheckLoanCtxt<'a, 'tcx> { None => { } } - self.check_assignment(assignment_id, assignment_span, assignee_cmt, mode); + self.check_assignment(assignment_id, assignment_span, assignee_cmt); } fn decl_without_init(&mut self, _id: ast::NodeId, _span: Span) { } @@ -782,16 +782,9 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { fn check_assignment(&self, assignment_id: ast::NodeId, assignment_span: Span, - assignee_cmt: mc::cmt<'tcx>, - mode: euv::MutateMode) { + assignee_cmt: mc::cmt<'tcx>) { debug!("check_assignment(assignee_cmt={:?})", assignee_cmt); - // Initializations never cause borrow errors as they only - // affect a fresh local. - if mode == euv::Init { - return - } - // Check that we don't invalidate any outstanding loans if let Some(loan_path) = opt_loan_path(&assignee_cmt) { let scope = region::CodeExtent::from_node_id(assignment_id); @@ -801,17 +794,15 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { }); } - // Local variables can always be assigned to, expect for reassignments - // of immutable variables (or assignments that invalidate loans, - // of course). + // Check for reassignments to (immutable) local variables. This + // needs to be done here instead of in check_loans because we + // depend on move data. if let mc::cat_local(local_id) = assignee_cmt.cat { - if assignee_cmt.mutbl.is_mutable() { - self.tcx().used_mut_nodes.borrow_mut().insert(local_id); - } - let lp = opt_loan_path(&assignee_cmt).unwrap(); self.move_data.each_assignment_of(assignment_id, &lp, |assign| { - if !assignee_cmt.mutbl.is_mutable() { + if assignee_cmt.mutbl.is_mutable() { + self.tcx().used_mut_nodes.borrow_mut().insert(local_id); + } else { self.bccx.report_reassigned_immutable_variable( assignment_span, &*lp, diff --git a/src/librustc_trans/save/dump_csv.rs b/src/librustc_trans/save/dump_csv.rs index d86242f39cea7..f747f2deec415 100644 --- a/src/librustc_trans/save/dump_csv.rs +++ b/src/librustc_trans/save/dump_csv.rs @@ -308,7 +308,7 @@ impl <'l, 'tcx> DumpCsvVisitor<'l, 'tcx> { debug!("process_method: {}:{}", id, token::get_name(name)); - let mut scope_id; + let scope_id; // The qualname for a method is the trait name or name of the struct in an impl in // which the method is declared in, followed by the method's name. let qualname = match self.tcx.impl_of_method(ast_util::local_def(id)) { diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index b6b5ac5c01eee..507bd9de2a11a 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -598,7 +598,7 @@ impl<'a> StringReader<'a> { /// Lex a LIT_INTEGER or a LIT_FLOAT fn scan_number(&mut self, c: char) -> token::Lit { - let mut num_digits; + let num_digits; let mut base = 10; let start_bpos = self.last_pos; diff --git a/src/test/compile-fail/lint-unused-mut-variables.rs b/src/test/compile-fail/lint-unused-mut-variables.rs index dcc82b8920ff5..8165dd0fa29c0 100644 --- a/src/test/compile-fail/lint-unused-mut-variables.rs +++ b/src/test/compile-fail/lint-unused-mut-variables.rs @@ -23,6 +23,15 @@ fn main() { let mut b = 3; //~ ERROR: variable does not need to be mutable let mut a = vec!(3); //~ ERROR: variable does not need to be mutable let (mut a, b) = (1, 2); //~ ERROR: variable does not need to be mutable + let mut a; //~ ERROR: variable does not need to be mutable + a = 3; + + let mut b; //~ ERROR: variable does not need to be mutable + if true { + b = 3; + } else { + b = 4; + } match 30 { mut x => {} //~ ERROR: variable does not need to be mutable