Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn by default on unused mutable variables #5966

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/libcore/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/flate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -844,7 +844,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;
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/rand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,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;
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/repr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/rt/uv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/rt/uv/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/rt/uvio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
6 changes: 3 additions & 3 deletions src/libcore/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/libcore/task/spawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/unstable/extfmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions src/libcore/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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);
}
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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;
Expand Down Expand Up @@ -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";
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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); }

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
13 changes: 12 additions & 1 deletion src/librustc/middle/borrowck/check_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/borrowck/gather_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
12 changes: 11 additions & 1 deletion src/librustc/middle/borrowck/loan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/check_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
57 changes: 57 additions & 0 deletions src/librustc/middle/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -86,6 +87,7 @@ pub enum lint {

unused_variable,
dead_assignment,
unused_mut,
}

pub fn level_to_str(lv: level) -> &'static str {
Expand Down Expand Up @@ -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)| {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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);
Expand Down
Loading