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.
This commit is contained in:
commit
aba93c6b60
52 changed files with 265 additions and 120 deletions
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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); }
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,24 +1733,29 @@ 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)) => {
|
||||
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(
|
||||
orig_span,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()));
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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| {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 }
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) => {
|
||||
|
|
42
src/test/compile-fail/unused-mut-variables.rs
Normal file
42
src/test/compile-fail/unused-mut-variables.rs
Normal file
|
@ -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];
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue