diff options
| author | bors <bors@rust-lang.org> | 2013-04-22 15:36:51 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-04-22 15:36:51 -0700 |
| commit | aba93c6b60a91fc4b6b60408e51b23dbee5f44c9 (patch) | |
| tree | 91d5ca30a8d1809161972cffa0b69b89a22750f2 /src | |
| parent | a6dd7dc1f2e1057719179e861a5a5ae55d6a8335 (diff) | |
| parent | c389d0b0dd2273c9f7d16917a1738509f5522491 (diff) | |
| download | rust-aba93c6b60a91fc4b6b60408e51b23dbee5f44c9.tar.gz rust-aba93c6b60a91fc4b6b60408e51b23dbee5f44c9.zip | |
auto merge of #5966 : alexcrichton/rust/issue-3083, r=graydon
Closes #3083. This takes a similar approach to #5797 where a set is present on the `tcx` of used mutable definitions. Everything is by default warned about, and analyses must explicitly add mutable definitions to this set so they're not warned about. Most of this was pretty straightforward, although there was one caveat that I ran into when implementing it. Apparently when the old modes are used (or maybe `legacy_modes`, I'm not sure) some different code paths are taken to cause spurious warnings to be issued which shouldn't be issued. I'm not really sure how modes even worked, so I was having a lot of trouble tracking this down. I figured that because they're a legacy thing that I'd just de-mode the compiler so that the warnings wouldn't be a problem anymore (or at least for the compiler). Other than that, the entire compiler compiles without warnings of unused mutable variables. To prevent bad warnings, #5965 should be landed (which in turn is waiting on #5963) before landing this. I figured I'd stick it out for review anyway though.
Diffstat (limited to 'src')
52 files changed, 265 insertions, 120 deletions
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 8c2175eeaca..27e03d2bf31 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -121,7 +121,7 @@ fn test_with_ref() { #[test] fn test_with_mut_ref() { let good = ~[1, 2, 3]; - let mut v = ~[1, 2]; + let v = ~[1, 2]; let c = Cell(v); do c.with_mut_ref() |v| { v.push(3); } let v = c.take(); diff --git a/src/libcore/flate.rs b/src/libcore/flate.rs index a4f12f7da7e..70c96c9c806 100644 --- a/src/libcore/flate.rs +++ b/src/libcore/flate.rs @@ -67,7 +67,7 @@ pub fn deflate_bytes(bytes: &const [u8]) -> ~[u8] { pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] { do vec::as_const_buf(bytes) |b, len| { unsafe { - let mut outsz : size_t = 0; + let outsz : size_t = 0; let res = rustrt::tinfl_decompress_mem_to_heap(b as *c_void, len as size_t, diff --git a/src/libcore/path.rs b/src/libcore/path.rs index 23f7e912f96..8328d42c35e 100644 --- a/src/libcore/path.rs +++ b/src/libcore/path.rs @@ -854,7 +854,7 @@ pub mod windows { while i < s.len() { if is_sep(s[i]) { let pre = s.slice(2, i).to_owned(); - let mut rest = s.slice(i, s.len()).to_owned(); + let rest = s.slice(i, s.len()).to_owned(); return Some((pre, rest)); } i += 1; diff --git a/src/libcore/rand.rs b/src/libcore/rand.rs index 1e33f382df5..919c7bbb036 100644 --- a/src/libcore/rand.rs +++ b/src/libcore/rand.rs @@ -742,7 +742,7 @@ struct XorShiftState { impl Rng for XorShiftState { fn next(&self) -> u32 { let x = self.x; - let mut t = x ^ (x << 11); + let t = x ^ (x << 11); self.x = self.y; self.y = self.z; self.z = self.w; diff --git a/src/libcore/repr.rs b/src/libcore/repr.rs index ca67e6366b5..03e44e00d88 100644 --- a/src/libcore/repr.rs +++ b/src/libcore/repr.rs @@ -210,7 +210,7 @@ pub impl ReprVisitor { #[inline(always)] fn visit_ptr_inner(&self, ptr: *c_void, inner: *TyDesc) -> bool { unsafe { - let mut u = ReprVisitor(ptr, self.writer); + let u = ReprVisitor(ptr, self.writer); let v = reflect::MovePtrAdaptor(u); visit_tydesc(inner, @v as @TyVisitor); true @@ -667,7 +667,7 @@ pub fn write_repr<T>(writer: @Writer, object: &T) { unsafe { let ptr = ptr::to_unsafe_ptr(object) as *c_void; let tydesc = intrinsic::get_tydesc::<T>(); - let mut u = ReprVisitor(ptr, writer); + let u = ReprVisitor(ptr, writer); let v = reflect::MovePtrAdaptor(u); visit_tydesc(tydesc, @v as @TyVisitor) } diff --git a/src/libcore/rt/uv/mod.rs b/src/libcore/rt/uv/mod.rs index 32757d6376e..4cbc8d70569 100644 --- a/src/libcore/rt/uv/mod.rs +++ b/src/libcore/rt/uv/mod.rs @@ -402,7 +402,7 @@ fn loop_smoke_test() { fn idle_new_then_close() { do run_in_bare_thread { let mut loop_ = Loop::new(); - let mut idle_watcher = { IdleWatcher::new(&mut loop_) }; + let idle_watcher = { IdleWatcher::new(&mut loop_) }; idle_watcher.close(); } } diff --git a/src/libcore/rt/uv/net.rs b/src/libcore/rt/uv/net.rs index b4a08c14928..bcfe8b2cfdf 100644 --- a/src/libcore/rt/uv/net.rs +++ b/src/libcore/rt/uv/net.rs @@ -393,7 +393,7 @@ fn connect_read() { let buf = vec_from_uv_buf(buf); rtdebug!("read cb!"); if status.is_none() { - let bytes = buf.unwrap(); + let _bytes = buf.unwrap(); rtdebug!("%s", bytes.slice(0, nread as uint).to_str()); } else { rtdebug!("status after read: %s", status.get().to_str()); diff --git a/src/libcore/rt/uvio.rs b/src/libcore/rt/uvio.rs index ff539739835..d4e547de383 100644 --- a/src/libcore/rt/uvio.rs +++ b/src/libcore/rt/uvio.rs @@ -206,7 +206,7 @@ impl TcpListener for UvTcpListener { let mut server_stream_watcher = server_stream_watcher; let mut loop_ = loop_from_watcher(&server_stream_watcher); let mut client_tcp_watcher = TcpWatcher::new(&mut loop_); - let mut client_tcp_watcher = client_tcp_watcher.as_stream(); + let client_tcp_watcher = client_tcp_watcher.as_stream(); // XXX: Need's to be surfaced in interface server_stream_watcher.accept(client_tcp_watcher); Some(~UvStream::new(client_tcp_watcher)) diff --git a/src/libcore/run.rs b/src/libcore/run.rs index 087ee6cdf85..f9d7f4a229c 100644 --- a/src/libcore/run.rs +++ b/src/libcore/run.rs @@ -343,7 +343,7 @@ pub fn start_program(prog: &str, args: &[~str]) -> @Program { fn force_destroy(&mut self) { destroy_repr(&mut self.r, true); } } - let mut repr = ProgRepr { + let repr = ProgRepr { pid: pid, in_fd: pipe_input.out, out_file: os::fdopen(pipe_output.in), diff --git a/src/libcore/str.rs b/src/libcore/str.rs index f1cacc6a348..38d68175679 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -673,7 +673,7 @@ pub fn levdistance(s: &str, t: &str) -> uint { for t.each_chari |j, tc| { - let mut next = dcol[j + 1]; + let next = dcol[j + 1]; if sc == tc { dcol[j + 1] = current; @@ -909,7 +909,7 @@ impl TotalOrd for @str { /// Bytewise slice less than fn lt(a: &str, b: &str) -> bool { let (a_len, b_len) = (a.len(), b.len()); - let mut end = uint::min(a_len, b_len); + let end = uint::min(a_len, b_len); let mut i = 0; while i < end { @@ -1715,7 +1715,7 @@ pub fn utf16_chars(v: &[u16], f: &fn(char)) { let len = vec::len(v); let mut i = 0u; while (i < len && v[i] != 0u16) { - let mut u = v[i]; + let u = v[i]; if u <= 0xD7FF_u16 || u >= 0xE000_u16 { f(u as char); diff --git a/src/libcore/task/spawn.rs b/src/libcore/task/spawn.rs index 118c4cc2312..d872d38a278 100644 --- a/src/libcore/task/spawn.rs +++ b/src/libcore/task/spawn.rs @@ -575,7 +575,7 @@ fn spawn_raw_oldsched(opts: TaskOpts, f: ~fn()) { }; assert!(!new_task.is_null()); // Getting killed after here would leak the task. - let mut notify_chan = if opts.notify_chan.is_none() { + let notify_chan = if opts.notify_chan.is_none() { None } else { Some(opts.notify_chan.swap_unwrap()) diff --git a/src/libcore/unstable/extfmt.rs b/src/libcore/unstable/extfmt.rs index ad3dce0a749..ee33e2ed20b 100644 --- a/src/libcore/unstable/extfmt.rs +++ b/src/libcore/unstable/extfmt.rs @@ -538,7 +538,7 @@ pub mod rt { pub fn conv_str(cv: Conv, s: &str, buf: &mut ~str) { // For strings, precision is the maximum characters // displayed - let mut unpadded = match cv.precision { + let unpadded = match cv.precision { CountImplied => s, CountIs(max) => if (max as uint) < str::char_len(s) { str::slice(s, 0, max as uint) @@ -596,7 +596,7 @@ pub mod rt { #[deriving(Eq)] pub enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat } - pub fn pad(cv: Conv, mut s: &str, head: Option<char>, mode: PadMode, + pub fn pad(cv: Conv, s: &str, head: Option<char>, mode: PadMode, buf: &mut ~str) { let headsize = match head { Some(_) => 1, _ => 0 }; let uwidth : uint = match cv.width { diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 1ef567e9cef..e478936ff65 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -1755,7 +1755,7 @@ impl<T: TotalOrd> TotalOrd for @[T] { fn lt<T:Ord>(a: &[T], b: &[T]) -> bool { let (a_len, b_len) = (a.len(), b.len()); - let mut end = uint::min(a_len, b_len); + let end = uint::min(a_len, b_len); let mut i = 0; while i < end { @@ -3897,7 +3897,7 @@ mod tests { #[test] fn reversed_mut() { - let mut v2 = reversed::<int>(~[10, 20]); + let v2 = reversed::<int>(~[10, 20]); assert!(v2[0] == 20); assert!(v2[1] == 10); } diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 3dfa318826b..a176b0163a4 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -273,7 +273,7 @@ pub mod write { let LLVMOptDefault = 2 as c_int; // -O2, -Os let LLVMOptAggressive = 3 as c_int; // -O3 - let mut CodeGenOptLevel = match opts.optimize { + let CodeGenOptLevel = match opts.optimize { session::No => LLVMOptNone, session::Less => LLVMOptLess, session::Default => LLVMOptDefault, @@ -294,7 +294,7 @@ pub mod write { return; } - let mut FileType; + let FileType; if output_type == output_type_object || output_type == output_type_exe { FileType = lib::llvm::ObjectFile; @@ -820,7 +820,7 @@ pub fn link_binary(sess: Session, cc_args.push(output.to_str()); cc_args.push(obj_filename.to_str()); - let mut lib_cmd; + let lib_cmd; let os = sess.targ_cfg.os; if os == session::os_macos { lib_cmd = ~"-dynamiclib"; diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index fae73d7faf2..c4f37c2170d 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -349,7 +349,7 @@ pub fn compile_upto(sess: Session, cfg: ast::crate_cfg, outputs: Option<@OutputFilenames>) -> (@ast::crate, Option<ty::ctxt>) { let time_passes = sess.time_passes(); - let mut crate = time(time_passes, ~"parsing", + let crate = time(time_passes, ~"parsing", || parse_input(sess, copy cfg, input) ); if upto == cu_parse { return (crate, None); } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index aaafc7c18d6..8515e0c6e9b 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1341,7 +1341,7 @@ pub static metadata_encoding_version : &'static [u8] = pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] { let wr = @io::BytesWriter(); - let mut stats = Stats { + let stats = Stats { inline_bytes: 0, attr_bytes: 0, dep_bytes: 0, diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index 4766fe1fb94..6f3075717ed 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -367,7 +367,18 @@ pub impl CheckLoanCtxt { // are only assigned once } else { match cmt.mutbl { - McDeclared | McInherited => { /*ok*/ } + McDeclared | McInherited => { + // Ok, but if this loan is a mutable loan, then mark the + // loan path (if it exists) as being used. This is similar + // to the check performed in loan.rs in issue_loan(). This + // type of use of mutable is different from issuing a loan, + // however. + for cmt.lp.each |lp| { + for lp.node_id().each |&id| { + self.tcx().used_mut_nodes.insert(id); + } + } + } McReadOnly | McImmutable => { self.bccx.span_err( ex.span, diff --git a/src/librustc/middle/borrowck/gather_loans.rs b/src/librustc/middle/borrowck/gather_loans.rs index 4f2e41dca5c..b8e0bba6b23 100644 --- a/src/librustc/middle/borrowck/gather_loans.rs +++ b/src/librustc/middle/borrowck/gather_loans.rs @@ -305,7 +305,7 @@ pub impl GatherLoanCtxt { let mcx = &mem_categorization_ctxt { tcx: self.tcx(), method_map: self.bccx.method_map}; - let mut cmt = mcx.cat_expr_autoderefd(expr, autoderefs); + let cmt = mcx.cat_expr_autoderefd(expr, autoderefs); debug!("after autoderef, cmt=%s", self.bccx.cmt_to_repr(cmt)); match autoref.kind { diff --git a/src/librustc/middle/borrowck/loan.rs b/src/librustc/middle/borrowck/loan.rs index 15189a552fb..aedd6bb5467 100644 --- a/src/librustc/middle/borrowck/loan.rs +++ b/src/librustc/middle/borrowck/loan.rs @@ -274,7 +274,17 @@ pub impl LoanContext { if !owns_lent_data || self.bccx.is_subregion_of(self.scope_region, scope_ub) { - if loan_kind.is_take() && !cmt.mutbl.is_mutable() { + if cmt.mutbl.is_mutable() { + // If this loan is a mutable loan, then mark the loan path (if + // it exists) as being used. This is similar to the check + // performed in check_loans.rs in check_assignment(), but this + // is for a different purpose of having the 'mut' qualifier. + for cmt.lp.each |lp| { + for lp.node_id().each |&id| { + self.tcx().used_mut_nodes.insert(id); + } + } + } else if loan_kind.is_take() { // We do not allow non-mutable data to be "taken" // under any circumstances. return Err(bckerr { diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index 1db8f8cc8de..8fc94cf51e2 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -481,7 +481,7 @@ pub fn specialize(cx: @MatchCheckCtxt, left_ty: ty::t) -> Option<~[@pat]> { // Sad, but I can't get rid of this easily - let mut r0 = copy *raw_pat(r[0]); + let r0 = copy *raw_pat(r[0]); match r0 { pat{id: pat_id, node: n, span: pat_span} => match n { diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 9087afe5969..bda97f4f530 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -13,6 +13,7 @@ use core::prelude::*; use driver::session::Session; use driver::session; use middle::ty; +use middle::pat_util; use util::ppaux::{ty_to_str}; use core::hashmap::HashMap; @@ -86,6 +87,7 @@ pub enum lint { unused_variable, dead_assignment, + unused_mut, } pub fn level_to_str(lv: level) -> &'static str { @@ -277,6 +279,13 @@ pub fn get_lint_dict() -> LintDict { desc: "detect assignments that will never be read", default: warn }), + + (~"unused_mut", + LintSpec { + lint: unused_mut, + desc: "detect mut variables which don't need to be mutable", + default: warn + }), ]; let mut map = HashMap::new(); do vec::consume(v) |_, (k, v)| { @@ -499,6 +508,7 @@ fn check_item(i: @ast::item, cx: ty::ctxt) { check_item_deprecated_mutable_fields(cx, i); check_item_deprecated_drop(cx, i); check_item_unused_unsafe(cx, i); + check_item_unused_mut(cx, i); } // Take a visitor, and modify it so that it will not proceed past subitems. @@ -954,6 +964,53 @@ fn check_item_unused_unsafe(cx: ty::ctxt, it: @ast::item) { visit::visit_item(it, (), visit); } +fn check_item_unused_mut(tcx: ty::ctxt, it: @ast::item) { + let check_pat: @fn(@ast::pat) = |p| { + let mut used = false; + let mut bindings = 0; + do pat_util::pat_bindings(tcx.def_map, p) |_, id, _, _| { + used = used || tcx.used_mut_nodes.contains(&id); + bindings += 1; + } + if !used { + let msg = if bindings == 1 { + ~"variable does not need to be mutable" + } else { + ~"variables do not need to be mutable" + }; + tcx.sess.span_lint(unused_mut, p.id, it.id, p.span, msg); + } + }; + + let visit_fn_decl: @fn(&ast::fn_decl) = |fd| { + for fd.inputs.each |arg| { + if arg.is_mutbl { + check_pat(arg.pat); + } + } + }; + + let visit = item_stopping_visitor( + visit::mk_simple_visitor(@visit::SimpleVisitor { + visit_local: |l| { + if l.node.is_mutbl { + check_pat(l.node.pat); + } + }, + visit_fn: |_, fd, _, _, _| visit_fn_decl(fd), + visit_ty_method: |tm| visit_fn_decl(&tm.decl), + visit_struct_method: |sm| visit_fn_decl(&sm.decl), + visit_trait_method: |tm| { + match *tm { + ast::required(ref tm) => visit_fn_decl(&tm.decl), + ast::provided(m) => visit_fn_decl(&m.decl), + } + }, + .. *visit::default_simple_visitor() + })); + visit::visit_item(it, (), visit); +} + fn check_fn(tcx: ty::ctxt, fk: &visit::fn_kind, decl: &ast::fn_decl, _body: &ast::blk, span: span, id: ast::node_id) { debug!("lint check_fn fk=%? id=%?", fk, id); diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 3136d7bf4e4..2b36ce4ce03 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1516,9 +1516,8 @@ fn check_local(local: @local, self: @Liveness, vt: vt<@Liveness>) { // Initializer: self.warn_about_unused_or_dead_vars_in_pat(local.node.pat); - if !local.node.is_mutbl { - self.check_for_reassignments_in_pat(local.node.pat); - } + self.check_for_reassignments_in_pat(local.node.pat, + local.node.is_mutbl); } None => { @@ -1702,12 +1701,15 @@ pub impl Liveness { match expr.node { expr_path(_) => { match *self.tcx.def_map.get(&expr.id) { - def_local(nid, false) => { - // Assignment to an immutable variable or argument: - // only legal if there is no later assignment. + def_local(nid, mutbl) => { + // Assignment to an immutable variable or argument: only legal + // if there is no later assignment. If this local is actually + // mutable, then check for a reassignment to flag the mutability + // as being used. let ln = self.live_node(expr.id, expr.span); let var = self.variable(nid, expr.span); - self.check_for_reassignment(ln, var, expr.span); + self.check_for_reassignment(ln, var, expr.span, + if mutbl {Some(nid)} else {None}); self.warn_about_dead_assign(expr.span, expr.id, ln, var); } def => { @@ -1731,23 +1733,28 @@ pub impl Liveness { } } - fn check_for_reassignments_in_pat(@self, pat: @pat) { - do self.pat_bindings(pat) |ln, var, sp, _id| { - self.check_for_reassignment(ln, var, sp); + fn check_for_reassignments_in_pat(@self, pat: @pat, mutbl: bool) { + do self.pat_bindings(pat) |ln, var, sp, id| { + self.check_for_reassignment(ln, var, sp, + if mutbl {Some(id)} else {None}); } } fn check_for_reassignment(@self, ln: LiveNode, var: Variable, - orig_span: span) { + orig_span: span, mutbl: Option<node_id>) { match self.assigned_on_exit(ln, var) { Some(ExprNode(span)) => { - self.tcx.sess.span_err( - span, - ~"re-assignment of immutable variable"); - - self.tcx.sess.span_note( - orig_span, - ~"prior assignment occurs here"); + match mutbl { + Some(id) => { self.tcx.used_mut_nodes.insert(id); } + None => { + self.tcx.sess.span_err( + span, + ~"re-assignment of immutable variable"); + self.tcx.sess.span_note( + orig_span, + ~"prior assignment occurs here"); + } + } } Some(lnk) => { self.tcx.sess.span_bug( diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 6473cb8e8e0..51e6860432a 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -351,6 +351,16 @@ pub impl MutabilityCategory { } } +pub impl loan_path { + fn node_id(&self) -> Option<ast::node_id> { + match *self { + lp_local(id) | lp_arg(id) => Some(id), + lp_deref(lp, _) | lp_comp(lp, _) => lp.node_id(), + lp_self => None + } + } +} + pub impl mem_categorization_ctxt { fn cat_expr(&self, expr: @ast::expr) -> cmt { match self.tcx.adjustments.find(&expr.id) { diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 41b372119cd..43c6a184d13 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -960,7 +960,7 @@ pub impl Resolver { // child name directly. Otherwise, we create or reuse an anonymous // module and add the child to that. - let mut module_; + let module_; match reduced_graph_parent { ModuleReducedGraphParent(parent_module) => { module_ = parent_module; @@ -1527,7 +1527,7 @@ pub impl Resolver { block: &blk, parent: ReducedGraphParent, visitor: vt<ReducedGraphParent>) { - let mut new_parent; + let new_parent; if self.block_needs_anonymous_module(block) { let block_id = block.node.id; @@ -2427,7 +2427,7 @@ pub impl Resolver { let merge_import_resolution = |ident, name_bindings: @mut NameBindings| { - let mut dest_import_resolution; + let dest_import_resolution; match module_.import_resolutions.find(ident) { None => { // Create a new import resolution from this child. @@ -2583,8 +2583,8 @@ pub impl Resolver { let module_prefix_result = self.resolve_module_prefix(module_, module_path); - let mut search_module; - let mut start_index; + let search_module; + let start_index; match module_prefix_result { Failed => { self.session.span_err(span, ~"unresolved name"); @@ -3221,7 +3221,7 @@ pub impl Resolver { allow_capturing_self: AllowCapturingSelfFlag) -> Option<def_like> { let mut def; - let mut is_ty_param; + let is_ty_param; match def_like { dl_def(d @ def_local(*)) | dl_def(d @ def_upvar(*)) | @@ -4530,7 +4530,7 @@ pub impl Resolver { -> Option<def> { let module_path_idents = self.intern_module_part_of_path(path); - let mut containing_module; + let containing_module; match self.resolve_module_path_for_import(self.current_module, module_path_idents, UseLexicalScope, @@ -4578,7 +4578,7 @@ pub impl Resolver { let root_module = self.graph_root.get_module(); - let mut containing_module; + let containing_module; match self.resolve_module_path_from_root(root_module, module_path_idents, 0, @@ -4622,7 +4622,7 @@ pub impl Resolver { span: span) -> Option<def> { // Check the local set of ribs. - let mut search_result; + let search_result; match namespace { ValueNS => { search_result = self.search_ribs(&mut self.value_ribs, ident, diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 7339003c614..dc59fcecb5a 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -248,7 +248,7 @@ pub enum opt_result { pub fn trans_opt(bcx: block, o: &Opt) -> opt_result { let _icx = bcx.insn_ctxt("match::trans_opt"); let ccx = bcx.ccx(); - let mut bcx = bcx; + let bcx = bcx; match *o { lit(ExprLit(lit_expr)) => { let datumblock = expr::trans_to_datum(bcx, lit_expr); diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 3301ed62cbe..7a174be1e57 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -292,7 +292,7 @@ pub fn trans_fn_ref_with_vtables( } // Find the actual function pointer. - let mut val = { + let val = { if def_id.crate == ast::local_crate { // Internal reference. get_item_val(ccx, def_id.node) @@ -415,7 +415,7 @@ pub fn trans_lang_call_with_type_params(bcx: block, type_params, None, fty); - let mut llfnty = type_of::type_of(callee.bcx.ccx(), + let llfnty = type_of::type_of(callee.bcx.ccx(), substituted); new_llval = PointerCast(callee.bcx, fn_data.llfn, llfnty); } @@ -712,7 +712,7 @@ pub fn trans_arg_expr(bcx: block, } }; let mut arg_datum = arg_datumblock.datum; - let mut bcx = arg_datumblock.bcx; + let bcx = arg_datumblock.bcx; debug!(" arg datum: %s", arg_datum.to_str(bcx.ccx())); diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index cb815506c39..4fc4cae464d 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -261,7 +261,7 @@ pub fn build_closure(bcx0: block, include_ret_handle: Option<ValueRef>) -> ClosureResult { let _icx = bcx0.insn_ctxt("closure::build_closure"); // If we need to, package up the iterator body to call - let mut bcx = bcx0;; + let bcx = bcx0;; let ccx = bcx.ccx(), tcx = ccx.tcx; // Package up the captured upvars diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 4b4d0869a3e..8727db27fff 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -192,7 +192,7 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock { } Some(&@AutoAddEnv(*)) => { let mut bcx = bcx; - let mut datum = unpack_datum!(bcx, { + let datum = unpack_datum!(bcx, { trans_to_datum_unadjusted(bcx, expr) }); add_env(bcx, expr, datum) @@ -1187,7 +1187,7 @@ fn trans_rec_or_struct(bcx: block, dest: Dest) -> block { let _icx = bcx.insn_ctxt("trans_rec"); - let mut bcx = bcx; + let bcx = bcx; let ty = node_id_type(bcx, id); let tcx = bcx.tcx(); @@ -1505,7 +1505,7 @@ fn trans_lazy_binop(bcx: block, b: @ast::expr) -> DatumBlock { let _icx = bcx.insn_ctxt("trans_lazy_binop"); let binop_ty = expr_ty(bcx, binop_expr); - let mut bcx = bcx; + let bcx = bcx; let Result {bcx: past_lhs, val: lhs} = { do base::with_scope_result(bcx, a.info(), ~"lhs") |bcx| { diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 956ee3bf144..cb15a2e8c64 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -567,7 +567,8 @@ pub fn trans_intrinsic(ccx: @CrateContext, set_fixed_stack_segment(fcx.llfn); } - let mut bcx = top_scope_block(fcx, None), lltop = bcx.llbb; + let mut bcx = top_scope_block(fcx, None); + let lltop = bcx.llbb; match *ccx.sess.str_of(item.ident) { ~"atomic_cxchg" => { let old = AtomicCmpXchg(bcx, diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index a0fcdf7fde8..052bea1b022 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -102,7 +102,7 @@ pub fn monomorphic_fn(ccx: @CrateContext, } let tpt = ty::lookup_item_type(ccx.tcx, fn_id); - let mut llitem_ty = tpt.ty; + let llitem_ty = tpt.ty; let map_node = session::expect(ccx.sess, ccx.tcx.items.find(&fn_id.node), || fmt!("While monomorphizing %?, couldn't find it in the item map \ diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 033fbecc08b..7cdd7c8a6f2 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -304,6 +304,11 @@ struct ctxt_ { // Set of used unsafe nodes (functions or blocks). Unsafe nodes not // present in this set can be warned about. used_unsafe: @mut HashSet<ast::node_id>, + + // Set of nodes which mark locals as mutable which end up getting used at + // some point. Local variable definitions not in this set can be warned + // about. + used_mut_nodes: @mut HashSet<ast::node_id>, } pub enum tbox_flag { @@ -933,6 +938,7 @@ pub fn mk_ctxt(s: session::Session, destructors: @mut HashSet::new(), trait_impls: @mut HashMap::new(), used_unsafe: @mut HashSet::new(), + used_mut_nodes: @mut HashSet::new(), } } diff --git a/src/librustc/middle/typeck/check/method.rs b/src/librustc/middle/typeck/check/method.rs index 9d8a1145f22..e778986b2d1 100644 --- a/src/librustc/middle/typeck/check/method.rs +++ b/src/librustc/middle/typeck/check/method.rs @@ -180,7 +180,7 @@ pub struct Candidate { pub impl<'self> LookupContext<'self> { fn do_lookup(&self, self_ty: ty::t) -> Option<method_map_entry> { - let mut self_ty = structurally_resolved_type(self.fcx, + let self_ty = structurally_resolved_type(self.fcx, self.self_expr.span, self_ty); diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index d6f892cac3c..ca9b3602d5d 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -1625,7 +1625,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, // block syntax lambdas; that is, lambdas without explicit // sigils. let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x)); - let mut error_happened = false; + let error_happened = false; let (expected_sig, expected_purity, expected_sigil, @@ -1706,7 +1706,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, field: ast::ident, tys: &[@ast::Ty]) { let tcx = fcx.ccx.tcx; - let mut bot = check_expr(fcx, base); + let bot = check_expr(fcx, base); let expr_t = structurally_resolved_type(fcx, expr.span, fcx.expr_ty(base)); let (base_t, derefs) = do_autoderef(fcx, expr.span, expr_t); @@ -2867,7 +2867,7 @@ pub fn check_decl_local(fcx: @mut FnCtxt, local: @ast::local) { } pub fn check_stmt(fcx: @mut FnCtxt, stmt: @ast::stmt) { - let mut node_id; + let node_id; let mut saw_bot = false; let mut saw_err = false; match stmt.node { @@ -3124,7 +3124,8 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt, ccx.tcx.enum_var_cache.insert(local_def(id), @variants); // Check that it is possible to represent this enum: - let mut outer = true, did = local_def(id); + let mut outer = true; + let did = local_def(id); if ty::type_structurally_contains(ccx.tcx, rty, |sty| { match *sty { ty::ty_enum(id, _) if id == did => { diff --git a/src/librustc/middle/typeck/check/vtable.rs b/src/librustc/middle/typeck/check/vtable.rs index 39715f295ad..ad173c69560 100644 --- a/src/librustc/middle/typeck/check/vtable.rs +++ b/src/librustc/middle/typeck/check/vtable.rs @@ -11,7 +11,7 @@ use core::prelude::*; use middle::resolve::Impl; -use middle::ty::{param_ty}; +use middle::ty::param_ty; use middle::ty; use middle::typeck::check::{FnCtxt, impl_self_ty}; use middle::typeck::check::{structurally_resolved_type}; diff --git a/src/librustc/middle/typeck/rscope.rs b/src/librustc/middle/typeck/rscope.rs index 62320a1d34d..869825e607e 100644 --- a/src/librustc/middle/typeck/rscope.rs +++ b/src/librustc/middle/typeck/rscope.rs @@ -158,7 +158,7 @@ impl MethodRscope { variance: Option<ty::region_variance>, rcvr_generics: &ast::Generics) -> MethodRscope { - let mut region_param_names = + let region_param_names = RegionParamNames::from_generics(rcvr_generics); MethodRscope { self_ty: self_ty, diff --git a/src/libstd/bitv.rs b/src/libstd/bitv.rs index d89ce4232b1..d1f6bf982a7 100644 --- a/src/libstd/bitv.rs +++ b/src/libstd/bitv.rs @@ -891,7 +891,7 @@ mod tests { #[test] fn test_0_elements() { let mut act; - let mut exp; + let exp; act = Bitv::new(0u, false); exp = vec::from_elem::<uint>(0u, 0u); assert!(act.eq_vec(exp)); diff --git a/src/libstd/deque.rs b/src/libstd/deque.rs index a88d13fda66..b120e40ec25 100644 --- a/src/libstd/deque.rs +++ b/src/libstd/deque.rs @@ -113,7 +113,7 @@ pub impl<T> Deque<T> { /// /// Fails if the deque is empty fn pop_front(&mut self) -> T { - let mut result = self.elts[self.lo].swap_unwrap(); + let result = self.elts[self.lo].swap_unwrap(); self.lo = (self.lo + 1u) % self.elts.len(); self.nelts -= 1u; result @@ -126,7 +126,7 @@ pub impl<T> Deque<T> { if self.hi == 0u { self.hi = self.elts.len() - 1u; } else { self.hi -= 1u; } - let mut result = self.elts[self.hi].swap_unwrap(); + let result = self.elts[self.hi].swap_unwrap(); self.elts[self.hi] = None; self.nelts -= 1u; result @@ -204,7 +204,7 @@ pub impl<T> Deque<T> { /// /// Fails if the deque is empty fn pop_front(&mut self) -> T { - let mut result = self.elts[self.lo].swap_unwrap(); + let result = self.elts[self.lo].swap_unwrap(); self.lo = (self.lo + 1u) % self.elts.len(); self.nelts -= 1u; result @@ -217,7 +217,7 @@ pub impl<T> Deque<T> { if self.hi == 0u { self.hi = self.elts.len() - 1u; } else { self.hi -= 1u; } - let mut result = self.elts[self.hi].swap_unwrap(); + let result = self.elts[self.hi].swap_unwrap(); self.elts[self.hi] = None; self.nelts -= 1u; result diff --git a/src/libstd/dlist.rs b/src/libstd/dlist.rs index f9de2e0f58a..e736273a5ee 100644 --- a/src/libstd/dlist.rs +++ b/src/libstd/dlist.rs @@ -220,7 +220,7 @@ pub impl<T> DList<T> { * node. O(1). */ fn push_head_n(@mut self, data: T) -> @mut DListNode<T> { - let mut nobe = DList::new_link(data); + let nobe = DList::new_link(data); self.add_head(nobe); nobe.get() } @@ -233,7 +233,7 @@ pub impl<T> DList<T> { * node. O(1). */ fn push_n(@mut self, data: T) -> @mut DListNode<T> { - let mut nobe = DList::new_link(data); + let nobe = DList::new_link(data); self.add_tail(nobe); nobe.get() } @@ -263,7 +263,7 @@ pub impl<T> DList<T> { data: T, neighbour: @mut DListNode<T> ) -> @mut DListNode<T> { - let mut nobe = DList::new_link(data); + let nobe = DList::new_link(data); self.insert_left(nobe, neighbour); nobe.get() } @@ -293,7 +293,7 @@ pub impl<T> DList<T> { data: T, neighbour: @mut DListNode<T> ) -> @mut DListNode<T> { - let mut nobe = DList::new_link(data); + let nobe = DList::new_link(data); self.insert_right(neighbour, nobe); nobe.get() } diff --git a/src/libstd/num/rational.rs b/src/libstd/num/rational.rs index ee6879e31d9..36652380bff 100644 --- a/src/libstd/num/rational.rs +++ b/src/libstd/num/rational.rs @@ -60,7 +60,7 @@ impl<T: Copy + Num + Ord> /// Put self into lowest terms, with denom > 0. fn reduce(&mut self) { - let mut g : T = gcd(self.numer, self.denom); + let g : T = gcd(self.numer, self.denom); self.numer /= g; self.denom /= g; @@ -505,4 +505,4 @@ mod test { test(s); } } -} \ No newline at end of file +} diff --git a/src/libstd/rope.rs b/src/libstd/rope.rs index 48ecc0fc851..33bc393e470 100644 --- a/src/libstd/rope.rs +++ b/src/libstd/rope.rs @@ -838,8 +838,7 @@ pub mod node { option::None => break, option::Some(x) => { //FIXME (#2744): Replace with memcpy or something similar - let mut local_buf: ~[u8] = - cast::transmute(*x.content); + let local_buf: ~[u8] = cast::transmute(*x.content); let mut i = x.byte_offset; while i < x.byte_len { buf[offset] = local_buf[i]; @@ -1156,7 +1155,7 @@ pub mod node { } pub fn empty() -> T { - let mut stack : ~[@Node] = ~[]; + let stack : ~[@Node] = ~[]; T { stack: stack, stackpos: -1 } } diff --git a/src/libstd/sha1.rs b/src/libstd/sha1.rs index 6aa4d1c54bc..7371250b38a 100644 --- a/src/libstd/sha1.rs +++ b/src/libstd/sha1.rs @@ -93,7 +93,7 @@ pub fn sha1() -> @Sha1 { assert!((vec::len(st.h) == digest_buf_len)); assert!((vec::uniq_len(st.work_buf) == work_buf_len)); let mut t: int; // Loop counter - let mut w = st.work_buf; + let w = st.work_buf; // Initialize the first 16 words of the vector w t = 0; @@ -260,7 +260,7 @@ pub fn sha1() -> @Sha1 { return s; } } - let mut st = Sha1State { + let st = Sha1State { h: vec::from_elem(digest_buf_len, 0u32), len_low: 0u32, len_high: 0u32, diff --git a/src/libstd/sort.rs b/src/libstd/sort.rs index 72a888fcc91..febaea637ef 100644 --- a/src/libstd/sort.rs +++ b/src/libstd/sort.rs @@ -239,7 +239,7 @@ fn binarysort<T:Copy + Ord>(array: &mut [T], start: uint) { } } assert!(left == right); - let mut n = start-left; + let n = start-left; copy_vec(array, left+1, array, left, n); array[left] = pivot; @@ -416,7 +416,7 @@ impl<T:Copy + Ord> MergeState<T> { } fn merge_at(&mut self, n: uint, array: &mut [T]) { - let mut size = self.runs.len(); + let size = self.runs.len(); assert!(size >= 2); assert!(n == size-2 || n == size-3); diff --git a/src/libstd/test.rs b/src/libstd/test.rs index 4ccbf207170..addc1da6394 100644 --- a/src/libstd/test.rs +++ b/src/libstd/test.rs @@ -427,8 +427,7 @@ fn run_tests(opts: &TestOpts, let filtered_descs = filtered_tests.map(|t| t.desc); callback(TeFiltered(filtered_descs)); - let mut (filtered_tests, - filtered_benchs) = + let (filtered_tests, filtered_benchs) = do vec::partition(filtered_tests) |e| { match e.testfn { StaticTestFn(_) | DynTestFn(_) => true, diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 70dc4d8cfeb..a763aa1592e 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -147,7 +147,7 @@ pub fn empty_tm() -> Tm { /// Returns the specified time in UTC pub fn at_utc(clock: Timespec) -> Tm { unsafe { - let mut Timespec { sec, nsec } = clock; + let Timespec { sec, nsec } = clock; let mut tm = empty_tm(); rustrt::rust_gmtime(sec, nsec, &mut tm); tm @@ -162,7 +162,7 @@ pub fn now_utc() -> Tm { /// Returns the specified time in the local timezone pub fn at(clock: Timespec) -> Tm { unsafe { - let mut Timespec { sec, nsec } = clock; + let Timespec { sec, nsec } = clock; let mut tm = empty_tm(); rustrt::rust_localtime(sec, nsec, &mut tm); tm diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs index 807371490db..c170ee5c119 100644 --- a/src/libsyntax/diagnostic.rs +++ b/src/libsyntax/diagnostic.rs @@ -342,7 +342,7 @@ fn highlight_lines_internal(cm: @codemap::CodeMap, while num > 0u { num /= 10u; digits += 1u; } // indent past |name:## | and the 0-offset column location - let mut left = str::len(fm.name) + digits + lo.col.to_uint() + 3u; + let left = str::len(fm.name) + digits + lo.col.to_uint() + 3u; let mut s = ~""; // Skip is the number of characters we need to skip because they are // part of the 'filename:line ' part of the previous line. diff --git a/src/libsyntax/ext/fmt.rs b/src/libsyntax/ext/fmt.rs index 3ebe844950a..6a877040f48 100644 --- a/src/libsyntax/ext/fmt.rs +++ b/src/libsyntax/ext/fmt.rs @@ -96,7 +96,7 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span, } } fn make_ty(cx: @ext_ctxt, sp: span, t: Ty) -> @ast::expr { - let mut rt_type; + let rt_type; match t { TyHex(c) => match c { CaseUpper => rt_type = ~"TyHexUpper", @@ -272,6 +272,7 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span, /* Translate each piece (portion of the fmt expression) by invoking the corresponding function in core::unstable::extfmt. Each function takes a buffer to insert data into along with the data being formatted. */ + let npieces = pieces.len(); do vec::consume(pieces) |i, pc| { match pc { /* Raw strings get appended via str::push_str */ @@ -279,9 +280,10 @@ fn pieces_to_expr(cx: @ext_ctxt, sp: span, let portion = mk_uniq_str(cx, fmt_sp, s); /* If this is the first portion, then initialize the local - buffer with it directly */ + buffer with it directly. If it's actually the only piece, + then there's no need for it to be mutable */ if i == 0 { - stms.push(mk_local(cx, fmt_sp, true, ident, portion)); + stms.push(mk_local(cx, fmt_sp, npieces > 1, ident, portion)); } else { let args = ~[mk_mut_addr_of(cx, fmt_sp, buf()), portion]; let call = mk_call_global(cx, diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index bf8f03d4bf6..f851b9781ab 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -73,7 +73,7 @@ impl parser_attr for Parser { self.expect(&token::LBRACKET); let meta_item = self.parse_meta_item(); self.expect(&token::RBRACKET); - let mut hi = self.span.hi; + let hi = self.span.hi; return spanned(lo, hi, ast::attribute_ { style: style, value: meta_item, is_sugared_doc: false }); @@ -141,16 +141,16 @@ impl parser_attr for Parser { token::EQ => { self.bump(); let lit = self.parse_lit(); - let mut hi = self.span.hi; + let hi = self.span.hi; @spanned(lo, hi, ast::meta_name_value(name, lit)) } token::LPAREN => { let inner_items = self.parse_meta_seq(); - let mut hi = self.span.hi; + let hi = self.span.hi; @spanned(lo, hi, ast::meta_list(name, inner_items)) } _ => { - let mut hi = self.span.hi; + let hi = self.span.hi; @spanned(lo, hi, ast::meta_word(name)) } } diff --git a/src/libsyntax/parse/comments.rs b/src/libsyntax/parse/comments.rs index 2f6bfd4cfc5..b73544e95d6 100644 --- a/src/libsyntax/parse/comments.rs +++ b/src/libsyntax/parse/comments.rs @@ -229,7 +229,7 @@ fn read_block_comment(rdr: @mut StringReader, debug!(">>> block comment"); let p = rdr.last_pos; let mut lines: ~[~str] = ~[]; - let mut col: CharPos = rdr.col; + let col: CharPos = rdr.col; bump(rdr); bump(rdr); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 42275aca0a3..21ea9f819b0 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -810,7 +810,7 @@ pub impl Parser { // This version of parse arg doesn't necessarily require // identifier names. fn parse_arg_general(&self, require_name: bool) -> arg { - let mut m; + let m; let mut is_mutbl = false; let pat = if require_name || self.is_named_argument() { m = self.parse_arg_mode(); @@ -1154,7 +1154,7 @@ pub impl Parser { let lo = self.span.lo; let mut hi = self.span.hi; - let mut ex: expr_; + let ex: expr_; if *self.token == token::LPAREN { self.bump(); @@ -1629,9 +1629,9 @@ pub impl Parser { // parse a prefix-operator expr fn parse_prefix_expr(&self) -> @expr { let lo = self.span.lo; - let mut hi; + let hi; - let mut ex; + let ex; match *self.token { token::NOT => { self.bump(); @@ -1781,7 +1781,7 @@ pub impl Parser { token::BINOPEQ(op) => { self.bump(); let rhs = self.parse_expr(); - let mut aop; + let aop; match op { token::PLUS => aop = add, token::MINUS => aop = subtract, @@ -1956,7 +1956,7 @@ pub impl Parser { let lo = self.last_span.lo; let cond = self.parse_expr(); let body = self.parse_block_no_value(); - let mut hi = body.span.hi; + let hi = body.span.hi; return self.mk_expr(lo, hi, expr_while(cond, body)); } @@ -1984,7 +1984,7 @@ pub impl Parser { let lo = self.last_span.lo; let body = self.parse_block_no_value(); - let mut hi = body.span.hi; + let hi = body.span.hi; return self.mk_expr(lo, hi, expr_loop(body, opt_ident)); } else { // This is a 'continue' expression @@ -2043,7 +2043,7 @@ pub impl Parser { arms.push(ast::arm { pats: pats, guard: guard, body: blk }); } - let mut hi = self.span.hi; + let hi = self.span.hi; self.bump(); return self.mk_expr(lo, hi, expr_match(discriminant, arms)); } @@ -2162,7 +2162,7 @@ pub impl Parser { let hi1 = self.last_span.lo; let fieldpath = ast_util::ident_to_path(mk_sp(lo1, hi1), fieldname); - let mut subpat; + let subpat; if *self.token == token::COLON { self.bump(); subpat = self.parse_pat(refutable); @@ -2183,7 +2183,7 @@ pub impl Parser { let lo = self.span.lo; let mut hi = self.span.hi; - let mut pat; + let pat; match *self.token { token::UNDERSCORE => { self.bump(); pat = pat_wild; } token::AT => { @@ -2534,7 +2534,7 @@ pub impl Parser { match self.parse_item_or_view_item(/*bad*/ copy item_attrs, true, false, false) { iovi_item(i) => { - let mut hi = i.span.hi; + let hi = i.span.hi; let decl = @spanned(lo, hi, decl_item(i)); return @spanned(lo, hi, stmt_decl(decl, self.get_id())); } @@ -2704,7 +2704,7 @@ pub impl Parser { } } } - let mut hi = self.span.hi; + let hi = self.span.hi; self.bump(); let bloc = ast::blk_ { view_items: view_items, @@ -3590,7 +3590,7 @@ pub impl Parser { let purity = self.parse_fn_purity(); let (ident, generics) = self.parse_fn_header(); let decl = self.parse_fn_decl(|p| p.parse_arg()); - let mut hi = self.span.hi; + let hi = self.span.hi; self.expect(&token::SEMI); @ast::foreign_item { ident: ident, attrs: attrs, @@ -3798,7 +3798,7 @@ pub impl Parser { } } self.bump(); - let mut actual_dtor = do the_dtor.map |dtor| { + let actual_dtor = do the_dtor.map |dtor| { let (d_body, d_attrs, d_s) = copy *dtor; codemap::spanned { node: ast::struct_dtor_ { id: self.get_id(), attrs: d_attrs, diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index eff7524e194..17add33d673 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -146,9 +146,9 @@ pub fn mk_printer(out: @io::Writer, linewidth: uint) -> @mut Printer { // fall behind. let n: uint = 3 * linewidth; debug!("mk_printer %u", linewidth); - let mut token: ~[token] = vec::from_elem(n, EOF); - let mut size: ~[int] = vec::from_elem(n, 0); - let mut scan_stack: ~[uint] = vec::from_elem(n, 0u); + let token: ~[token] = vec::from_elem(n, EOF); + let size: ~[int] = vec::from_elem(n, 0); + let scan_stack: ~[uint] = vec::from_elem(n, 0u); @mut Printer { out: @out, buf_len: n, diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 8cf73599562..ce772ca7c35 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1972,7 +1972,7 @@ pub fn print_ty_fn(s: @ps, pub fn maybe_print_trailing_comment(s: @ps, span: codemap::span, next_pos: Option<BytePos>) { - let mut cm; + let cm; match s.cm { Some(ccm) => cm = ccm, _ => return } match next_comment(s) { Some(ref cmnt) => { diff --git a/src/test/compile-fail/unused-mut-variables.rs b/src/test/compile-fail/unused-mut-variables.rs new file mode 100644 index 00000000000..d1223cd8893 --- /dev/null +++ b/src/test/compile-fail/unused-mut-variables.rs @@ -0,0 +1,42 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Exercise the unused_mut attribute in some positive and negative cases + +#[allow(dead_assignment)]; +#[allow(unused_variable)]; +#[deny(unused_mut)]; + +fn main() { + // negative cases + let mut a = 3; //~ ERROR: variable does not need to be mutable + let mut a = 2, b = 3; //~ ERROR: variable does not need to be mutable + //~^ ERROR: variable does not need to be mutable + let mut a = ~[3]; //~ ERROR: variable does not need to be mutable + + // positive cases + let mut a = 2; + a = 3; + let mut a = ~[]; + a.push(3); + let mut a = ~[]; + do callback { + a.push(3); + } +} + +fn callback(f: &fn()) {} + +// make sure the lint attribute can be turned off +#[allow(unused_mut)] +fn foo(mut a: int) { + let mut a = 3; + let mut b = ~[2]; +} |
