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]
|
#[test]
|
||||||
fn test_with_mut_ref() {
|
fn test_with_mut_ref() {
|
||||||
let good = ~[1, 2, 3];
|
let good = ~[1, 2, 3];
|
||||||
let mut v = ~[1, 2];
|
let v = ~[1, 2];
|
||||||
let c = Cell(v);
|
let c = Cell(v);
|
||||||
do c.with_mut_ref() |v| { v.push(3); }
|
do c.with_mut_ref() |v| { v.push(3); }
|
||||||
let v = c.take();
|
let v = c.take();
|
||||||
|
|
|
@ -67,7 +67,7 @@ pub fn deflate_bytes(bytes: &const [u8]) -> ~[u8] {
|
||||||
pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] {
|
pub fn inflate_bytes(bytes: &const [u8]) -> ~[u8] {
|
||||||
do vec::as_const_buf(bytes) |b, len| {
|
do vec::as_const_buf(bytes) |b, len| {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut outsz : size_t = 0;
|
let outsz : size_t = 0;
|
||||||
let res =
|
let res =
|
||||||
rustrt::tinfl_decompress_mem_to_heap(b as *c_void,
|
rustrt::tinfl_decompress_mem_to_heap(b as *c_void,
|
||||||
len as size_t,
|
len as size_t,
|
||||||
|
|
|
@ -854,7 +854,7 @@ pub mod windows {
|
||||||
while i < s.len() {
|
while i < s.len() {
|
||||||
if is_sep(s[i]) {
|
if is_sep(s[i]) {
|
||||||
let pre = s.slice(2, i).to_owned();
|
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));
|
return Some((pre, rest));
|
||||||
}
|
}
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|
|
@ -742,7 +742,7 @@ struct XorShiftState {
|
||||||
impl Rng for XorShiftState {
|
impl Rng for XorShiftState {
|
||||||
fn next(&self) -> u32 {
|
fn next(&self) -> u32 {
|
||||||
let x = self.x;
|
let x = self.x;
|
||||||
let mut t = x ^ (x << 11);
|
let t = x ^ (x << 11);
|
||||||
self.x = self.y;
|
self.x = self.y;
|
||||||
self.y = self.z;
|
self.y = self.z;
|
||||||
self.z = self.w;
|
self.z = self.w;
|
||||||
|
|
|
@ -210,7 +210,7 @@ pub impl ReprVisitor {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn visit_ptr_inner(&self, ptr: *c_void, inner: *TyDesc) -> bool {
|
fn visit_ptr_inner(&self, ptr: *c_void, inner: *TyDesc) -> bool {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut u = ReprVisitor(ptr, self.writer);
|
let u = ReprVisitor(ptr, self.writer);
|
||||||
let v = reflect::MovePtrAdaptor(u);
|
let v = reflect::MovePtrAdaptor(u);
|
||||||
visit_tydesc(inner, @v as @TyVisitor);
|
visit_tydesc(inner, @v as @TyVisitor);
|
||||||
true
|
true
|
||||||
|
@ -667,7 +667,7 @@ pub fn write_repr<T>(writer: @Writer, object: &T) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = ptr::to_unsafe_ptr(object) as *c_void;
|
let ptr = ptr::to_unsafe_ptr(object) as *c_void;
|
||||||
let tydesc = intrinsic::get_tydesc::<T>();
|
let tydesc = intrinsic::get_tydesc::<T>();
|
||||||
let mut u = ReprVisitor(ptr, writer);
|
let u = ReprVisitor(ptr, writer);
|
||||||
let v = reflect::MovePtrAdaptor(u);
|
let v = reflect::MovePtrAdaptor(u);
|
||||||
visit_tydesc(tydesc, @v as @TyVisitor)
|
visit_tydesc(tydesc, @v as @TyVisitor)
|
||||||
}
|
}
|
||||||
|
|
|
@ -402,7 +402,7 @@ fn loop_smoke_test() {
|
||||||
fn idle_new_then_close() {
|
fn idle_new_then_close() {
|
||||||
do run_in_bare_thread {
|
do run_in_bare_thread {
|
||||||
let mut loop_ = Loop::new();
|
let mut loop_ = Loop::new();
|
||||||
let mut idle_watcher = { IdleWatcher::new(&mut loop_) };
|
let idle_watcher = { IdleWatcher::new(&mut loop_) };
|
||||||
idle_watcher.close();
|
idle_watcher.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -393,7 +393,7 @@ fn connect_read() {
|
||||||
let buf = vec_from_uv_buf(buf);
|
let buf = vec_from_uv_buf(buf);
|
||||||
rtdebug!("read cb!");
|
rtdebug!("read cb!");
|
||||||
if status.is_none() {
|
if status.is_none() {
|
||||||
let bytes = buf.unwrap();
|
let _bytes = buf.unwrap();
|
||||||
rtdebug!("%s", bytes.slice(0, nread as uint).to_str());
|
rtdebug!("%s", bytes.slice(0, nread as uint).to_str());
|
||||||
} else {
|
} else {
|
||||||
rtdebug!("status after read: %s", status.get().to_str());
|
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 server_stream_watcher = server_stream_watcher;
|
||||||
let mut loop_ = loop_from_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 = 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
|
// XXX: Need's to be surfaced in interface
|
||||||
server_stream_watcher.accept(client_tcp_watcher);
|
server_stream_watcher.accept(client_tcp_watcher);
|
||||||
Some(~UvStream::new(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); }
|
fn force_destroy(&mut self) { destroy_repr(&mut self.r, true); }
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut repr = ProgRepr {
|
let repr = ProgRepr {
|
||||||
pid: pid,
|
pid: pid,
|
||||||
in_fd: pipe_input.out,
|
in_fd: pipe_input.out,
|
||||||
out_file: os::fdopen(pipe_output.in),
|
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| {
|
for t.each_chari |j, tc| {
|
||||||
|
|
||||||
let mut next = dcol[j + 1];
|
let next = dcol[j + 1];
|
||||||
|
|
||||||
if sc == tc {
|
if sc == tc {
|
||||||
dcol[j + 1] = current;
|
dcol[j + 1] = current;
|
||||||
|
@ -909,7 +909,7 @@ impl TotalOrd for @str {
|
||||||
/// Bytewise slice less than
|
/// Bytewise slice less than
|
||||||
fn lt(a: &str, b: &str) -> bool {
|
fn lt(a: &str, b: &str) -> bool {
|
||||||
let (a_len, b_len) = (a.len(), b.len());
|
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;
|
let mut i = 0;
|
||||||
while i < end {
|
while i < end {
|
||||||
|
@ -1715,7 +1715,7 @@ pub fn utf16_chars(v: &[u16], f: &fn(char)) {
|
||||||
let len = vec::len(v);
|
let len = vec::len(v);
|
||||||
let mut i = 0u;
|
let mut i = 0u;
|
||||||
while (i < len && v[i] != 0u16) {
|
while (i < len && v[i] != 0u16) {
|
||||||
let mut u = v[i];
|
let u = v[i];
|
||||||
|
|
||||||
if u <= 0xD7FF_u16 || u >= 0xE000_u16 {
|
if u <= 0xD7FF_u16 || u >= 0xE000_u16 {
|
||||||
f(u as char);
|
f(u as char);
|
||||||
|
|
|
@ -575,7 +575,7 @@ fn spawn_raw_oldsched(opts: TaskOpts, f: ~fn()) {
|
||||||
};
|
};
|
||||||
assert!(!new_task.is_null());
|
assert!(!new_task.is_null());
|
||||||
// Getting killed after here would leak the task.
|
// 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
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(opts.notify_chan.swap_unwrap())
|
Some(opts.notify_chan.swap_unwrap())
|
||||||
|
|
|
@ -538,7 +538,7 @@ pub mod rt {
|
||||||
pub fn conv_str(cv: Conv, s: &str, buf: &mut ~str) {
|
pub fn conv_str(cv: Conv, s: &str, buf: &mut ~str) {
|
||||||
// For strings, precision is the maximum characters
|
// For strings, precision is the maximum characters
|
||||||
// displayed
|
// displayed
|
||||||
let mut unpadded = match cv.precision {
|
let unpadded = match cv.precision {
|
||||||
CountImplied => s,
|
CountImplied => s,
|
||||||
CountIs(max) => if (max as uint) < str::char_len(s) {
|
CountIs(max) => if (max as uint) < str::char_len(s) {
|
||||||
str::slice(s, 0, max as uint)
|
str::slice(s, 0, max as uint)
|
||||||
|
@ -596,7 +596,7 @@ pub mod rt {
|
||||||
#[deriving(Eq)]
|
#[deriving(Eq)]
|
||||||
pub enum PadMode { PadSigned, PadUnsigned, PadNozero, PadFloat }
|
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) {
|
buf: &mut ~str) {
|
||||||
let headsize = match head { Some(_) => 1, _ => 0 };
|
let headsize = match head { Some(_) => 1, _ => 0 };
|
||||||
let uwidth : uint = match cv.width {
|
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 {
|
fn lt<T:Ord>(a: &[T], b: &[T]) -> bool {
|
||||||
let (a_len, b_len) = (a.len(), b.len());
|
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;
|
let mut i = 0;
|
||||||
while i < end {
|
while i < end {
|
||||||
|
@ -3897,7 +3897,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reversed_mut() {
|
fn reversed_mut() {
|
||||||
let mut v2 = reversed::<int>(~[10, 20]);
|
let v2 = reversed::<int>(~[10, 20]);
|
||||||
assert!(v2[0] == 20);
|
assert!(v2[0] == 20);
|
||||||
assert!(v2[1] == 10);
|
assert!(v2[1] == 10);
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,7 +273,7 @@ pub mod write {
|
||||||
let LLVMOptDefault = 2 as c_int; // -O2, -Os
|
let LLVMOptDefault = 2 as c_int; // -O2, -Os
|
||||||
let LLVMOptAggressive = 3 as c_int; // -O3
|
let LLVMOptAggressive = 3 as c_int; // -O3
|
||||||
|
|
||||||
let mut CodeGenOptLevel = match opts.optimize {
|
let CodeGenOptLevel = match opts.optimize {
|
||||||
session::No => LLVMOptNone,
|
session::No => LLVMOptNone,
|
||||||
session::Less => LLVMOptLess,
|
session::Less => LLVMOptLess,
|
||||||
session::Default => LLVMOptDefault,
|
session::Default => LLVMOptDefault,
|
||||||
|
@ -294,7 +294,7 @@ pub mod write {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut FileType;
|
let FileType;
|
||||||
if output_type == output_type_object ||
|
if output_type == output_type_object ||
|
||||||
output_type == output_type_exe {
|
output_type == output_type_exe {
|
||||||
FileType = lib::llvm::ObjectFile;
|
FileType = lib::llvm::ObjectFile;
|
||||||
|
@ -820,7 +820,7 @@ pub fn link_binary(sess: Session,
|
||||||
cc_args.push(output.to_str());
|
cc_args.push(output.to_str());
|
||||||
cc_args.push(obj_filename.to_str());
|
cc_args.push(obj_filename.to_str());
|
||||||
|
|
||||||
let mut lib_cmd;
|
let lib_cmd;
|
||||||
let os = sess.targ_cfg.os;
|
let os = sess.targ_cfg.os;
|
||||||
if os == session::os_macos {
|
if os == session::os_macos {
|
||||||
lib_cmd = ~"-dynamiclib";
|
lib_cmd = ~"-dynamiclib";
|
||||||
|
|
|
@ -349,7 +349,7 @@ pub fn compile_upto(sess: Session, cfg: ast::crate_cfg,
|
||||||
outputs: Option<@OutputFilenames>)
|
outputs: Option<@OutputFilenames>)
|
||||||
-> (@ast::crate, Option<ty::ctxt>) {
|
-> (@ast::crate, Option<ty::ctxt>) {
|
||||||
let time_passes = sess.time_passes();
|
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) );
|
|| parse_input(sess, copy cfg, input) );
|
||||||
if upto == cu_parse { return (crate, None); }
|
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] {
|
pub fn encode_metadata(parms: EncodeParams, crate: &crate) -> ~[u8] {
|
||||||
let wr = @io::BytesWriter();
|
let wr = @io::BytesWriter();
|
||||||
let mut stats = Stats {
|
let stats = Stats {
|
||||||
inline_bytes: 0,
|
inline_bytes: 0,
|
||||||
attr_bytes: 0,
|
attr_bytes: 0,
|
||||||
dep_bytes: 0,
|
dep_bytes: 0,
|
||||||
|
|
|
@ -367,7 +367,18 @@ pub impl CheckLoanCtxt {
|
||||||
// are only assigned once
|
// are only assigned once
|
||||||
} else {
|
} else {
|
||||||
match cmt.mutbl {
|
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 => {
|
McReadOnly | McImmutable => {
|
||||||
self.bccx.span_err(
|
self.bccx.span_err(
|
||||||
ex.span,
|
ex.span,
|
||||||
|
|
|
@ -305,7 +305,7 @@ pub impl GatherLoanCtxt {
|
||||||
let mcx = &mem_categorization_ctxt {
|
let mcx = &mem_categorization_ctxt {
|
||||||
tcx: self.tcx(),
|
tcx: self.tcx(),
|
||||||
method_map: self.bccx.method_map};
|
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));
|
debug!("after autoderef, cmt=%s", self.bccx.cmt_to_repr(cmt));
|
||||||
|
|
||||||
match autoref.kind {
|
match autoref.kind {
|
||||||
|
|
|
@ -274,7 +274,17 @@ pub impl LoanContext {
|
||||||
if !owns_lent_data ||
|
if !owns_lent_data ||
|
||||||
self.bccx.is_subregion_of(self.scope_region, scope_ub)
|
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"
|
// We do not allow non-mutable data to be "taken"
|
||||||
// under any circumstances.
|
// under any circumstances.
|
||||||
return Err(bckerr {
|
return Err(bckerr {
|
||||||
|
|
|
@ -481,7 +481,7 @@ pub fn specialize(cx: @MatchCheckCtxt,
|
||||||
left_ty: ty::t)
|
left_ty: ty::t)
|
||||||
-> Option<~[@pat]> {
|
-> Option<~[@pat]> {
|
||||||
// Sad, but I can't get rid of this easily
|
// 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 {
|
match r0 {
|
||||||
pat{id: pat_id, node: n, span: pat_span} =>
|
pat{id: pat_id, node: n, span: pat_span} =>
|
||||||
match n {
|
match n {
|
||||||
|
|
|
@ -13,6 +13,7 @@ use core::prelude::*;
|
||||||
use driver::session::Session;
|
use driver::session::Session;
|
||||||
use driver::session;
|
use driver::session;
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
|
use middle::pat_util;
|
||||||
use util::ppaux::{ty_to_str};
|
use util::ppaux::{ty_to_str};
|
||||||
|
|
||||||
use core::hashmap::HashMap;
|
use core::hashmap::HashMap;
|
||||||
|
@ -86,6 +87,7 @@ pub enum lint {
|
||||||
|
|
||||||
unused_variable,
|
unused_variable,
|
||||||
dead_assignment,
|
dead_assignment,
|
||||||
|
unused_mut,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn level_to_str(lv: level) -> &'static str {
|
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",
|
desc: "detect assignments that will never be read",
|
||||||
default: warn
|
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();
|
let mut map = HashMap::new();
|
||||||
do vec::consume(v) |_, (k, v)| {
|
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_mutable_fields(cx, i);
|
||||||
check_item_deprecated_drop(cx, i);
|
check_item_deprecated_drop(cx, i);
|
||||||
check_item_unused_unsafe(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.
|
// 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);
|
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,
|
fn check_fn(tcx: ty::ctxt, fk: &visit::fn_kind, decl: &ast::fn_decl,
|
||||||
_body: &ast::blk, span: span, id: ast::node_id) {
|
_body: &ast::blk, span: span, id: ast::node_id) {
|
||||||
debug!("lint check_fn fk=%? id=%?", fk, id);
|
debug!("lint check_fn fk=%? id=%?", fk, id);
|
||||||
|
|
|
@ -1516,9 +1516,8 @@ fn check_local(local: @local, self: @Liveness, vt: vt<@Liveness>) {
|
||||||
|
|
||||||
// Initializer:
|
// Initializer:
|
||||||
self.warn_about_unused_or_dead_vars_in_pat(local.node.pat);
|
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 => {
|
None => {
|
||||||
|
|
||||||
|
@ -1702,12 +1701,15 @@ pub impl Liveness {
|
||||||
match expr.node {
|
match expr.node {
|
||||||
expr_path(_) => {
|
expr_path(_) => {
|
||||||
match *self.tcx.def_map.get(&expr.id) {
|
match *self.tcx.def_map.get(&expr.id) {
|
||||||
def_local(nid, false) => {
|
def_local(nid, mutbl) => {
|
||||||
// Assignment to an immutable variable or argument:
|
// Assignment to an immutable variable or argument: only legal
|
||||||
// only legal if there is no later assignment.
|
// 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 ln = self.live_node(expr.id, expr.span);
|
||||||
let var = self.variable(nid, 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);
|
self.warn_about_dead_assign(expr.span, expr.id, ln, var);
|
||||||
}
|
}
|
||||||
def => {
|
def => {
|
||||||
|
@ -1731,24 +1733,29 @@ pub impl Liveness {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_for_reassignments_in_pat(@self, pat: @pat) {
|
fn check_for_reassignments_in_pat(@self, pat: @pat, mutbl: bool) {
|
||||||
do self.pat_bindings(pat) |ln, var, sp, _id| {
|
do self.pat_bindings(pat) |ln, var, sp, id| {
|
||||||
self.check_for_reassignment(ln, var, sp);
|
self.check_for_reassignment(ln, var, sp,
|
||||||
|
if mutbl {Some(id)} else {None});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_for_reassignment(@self, ln: LiveNode, var: Variable,
|
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) {
|
match self.assigned_on_exit(ln, var) {
|
||||||
Some(ExprNode(span)) => {
|
Some(ExprNode(span)) => {
|
||||||
|
match mutbl {
|
||||||
|
Some(id) => { self.tcx.used_mut_nodes.insert(id); }
|
||||||
|
None => {
|
||||||
self.tcx.sess.span_err(
|
self.tcx.sess.span_err(
|
||||||
span,
|
span,
|
||||||
~"re-assignment of immutable variable");
|
~"re-assignment of immutable variable");
|
||||||
|
|
||||||
self.tcx.sess.span_note(
|
self.tcx.sess.span_note(
|
||||||
orig_span,
|
orig_span,
|
||||||
~"prior assignment occurs here");
|
~"prior assignment occurs here");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some(lnk) => {
|
Some(lnk) => {
|
||||||
self.tcx.sess.span_bug(
|
self.tcx.sess.span_bug(
|
||||||
orig_span,
|
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 {
|
pub impl mem_categorization_ctxt {
|
||||||
fn cat_expr(&self, expr: @ast::expr) -> cmt {
|
fn cat_expr(&self, expr: @ast::expr) -> cmt {
|
||||||
match self.tcx.adjustments.find(&expr.id) {
|
match self.tcx.adjustments.find(&expr.id) {
|
||||||
|
|
|
@ -960,7 +960,7 @@ pub impl Resolver {
|
||||||
// child name directly. Otherwise, we create or reuse an anonymous
|
// child name directly. Otherwise, we create or reuse an anonymous
|
||||||
// module and add the child to that.
|
// module and add the child to that.
|
||||||
|
|
||||||
let mut module_;
|
let module_;
|
||||||
match reduced_graph_parent {
|
match reduced_graph_parent {
|
||||||
ModuleReducedGraphParent(parent_module) => {
|
ModuleReducedGraphParent(parent_module) => {
|
||||||
module_ = parent_module;
|
module_ = parent_module;
|
||||||
|
@ -1527,7 +1527,7 @@ pub impl Resolver {
|
||||||
block: &blk,
|
block: &blk,
|
||||||
parent: ReducedGraphParent,
|
parent: ReducedGraphParent,
|
||||||
visitor: vt<ReducedGraphParent>) {
|
visitor: vt<ReducedGraphParent>) {
|
||||||
let mut new_parent;
|
let new_parent;
|
||||||
if self.block_needs_anonymous_module(block) {
|
if self.block_needs_anonymous_module(block) {
|
||||||
let block_id = block.node.id;
|
let block_id = block.node.id;
|
||||||
|
|
||||||
|
@ -2427,7 +2427,7 @@ pub impl Resolver {
|
||||||
|
|
||||||
let merge_import_resolution = |ident,
|
let merge_import_resolution = |ident,
|
||||||
name_bindings: @mut NameBindings| {
|
name_bindings: @mut NameBindings| {
|
||||||
let mut dest_import_resolution;
|
let dest_import_resolution;
|
||||||
match module_.import_resolutions.find(ident) {
|
match module_.import_resolutions.find(ident) {
|
||||||
None => {
|
None => {
|
||||||
// Create a new import resolution from this child.
|
// Create a new import resolution from this child.
|
||||||
|
@ -2583,8 +2583,8 @@ pub impl Resolver {
|
||||||
let module_prefix_result = self.resolve_module_prefix(module_,
|
let module_prefix_result = self.resolve_module_prefix(module_,
|
||||||
module_path);
|
module_path);
|
||||||
|
|
||||||
let mut search_module;
|
let search_module;
|
||||||
let mut start_index;
|
let start_index;
|
||||||
match module_prefix_result {
|
match module_prefix_result {
|
||||||
Failed => {
|
Failed => {
|
||||||
self.session.span_err(span, ~"unresolved name");
|
self.session.span_err(span, ~"unresolved name");
|
||||||
|
@ -3221,7 +3221,7 @@ pub impl Resolver {
|
||||||
allow_capturing_self: AllowCapturingSelfFlag)
|
allow_capturing_self: AllowCapturingSelfFlag)
|
||||||
-> Option<def_like> {
|
-> Option<def_like> {
|
||||||
let mut def;
|
let mut def;
|
||||||
let mut is_ty_param;
|
let is_ty_param;
|
||||||
|
|
||||||
match def_like {
|
match def_like {
|
||||||
dl_def(d @ def_local(*)) | dl_def(d @ def_upvar(*)) |
|
dl_def(d @ def_local(*)) | dl_def(d @ def_upvar(*)) |
|
||||||
|
@ -4530,7 +4530,7 @@ pub impl Resolver {
|
||||||
-> Option<def> {
|
-> Option<def> {
|
||||||
let module_path_idents = self.intern_module_part_of_path(path);
|
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,
|
match self.resolve_module_path_for_import(self.current_module,
|
||||||
module_path_idents,
|
module_path_idents,
|
||||||
UseLexicalScope,
|
UseLexicalScope,
|
||||||
|
@ -4578,7 +4578,7 @@ pub impl Resolver {
|
||||||
|
|
||||||
let root_module = self.graph_root.get_module();
|
let root_module = self.graph_root.get_module();
|
||||||
|
|
||||||
let mut containing_module;
|
let containing_module;
|
||||||
match self.resolve_module_path_from_root(root_module,
|
match self.resolve_module_path_from_root(root_module,
|
||||||
module_path_idents,
|
module_path_idents,
|
||||||
0,
|
0,
|
||||||
|
@ -4622,7 +4622,7 @@ pub impl Resolver {
|
||||||
span: span)
|
span: span)
|
||||||
-> Option<def> {
|
-> Option<def> {
|
||||||
// Check the local set of ribs.
|
// Check the local set of ribs.
|
||||||
let mut search_result;
|
let search_result;
|
||||||
match namespace {
|
match namespace {
|
||||||
ValueNS => {
|
ValueNS => {
|
||||||
search_result = self.search_ribs(&mut self.value_ribs, ident,
|
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 {
|
pub fn trans_opt(bcx: block, o: &Opt) -> opt_result {
|
||||||
let _icx = bcx.insn_ctxt("match::trans_opt");
|
let _icx = bcx.insn_ctxt("match::trans_opt");
|
||||||
let ccx = bcx.ccx();
|
let ccx = bcx.ccx();
|
||||||
let mut bcx = bcx;
|
let bcx = bcx;
|
||||||
match *o {
|
match *o {
|
||||||
lit(ExprLit(lit_expr)) => {
|
lit(ExprLit(lit_expr)) => {
|
||||||
let datumblock = expr::trans_to_datum(bcx, 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.
|
// Find the actual function pointer.
|
||||||
let mut val = {
|
let val = {
|
||||||
if def_id.crate == ast::local_crate {
|
if def_id.crate == ast::local_crate {
|
||||||
// Internal reference.
|
// Internal reference.
|
||||||
get_item_val(ccx, def_id.node)
|
get_item_val(ccx, def_id.node)
|
||||||
|
@ -415,7 +415,7 @@ pub fn trans_lang_call_with_type_params(bcx: block,
|
||||||
type_params,
|
type_params,
|
||||||
None,
|
None,
|
||||||
fty);
|
fty);
|
||||||
let mut llfnty = type_of::type_of(callee.bcx.ccx(),
|
let llfnty = type_of::type_of(callee.bcx.ccx(),
|
||||||
substituted);
|
substituted);
|
||||||
new_llval = PointerCast(callee.bcx, fn_data.llfn, llfnty);
|
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 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()));
|
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 {
|
include_ret_handle: Option<ValueRef>) -> ClosureResult {
|
||||||
let _icx = bcx0.insn_ctxt("closure::build_closure");
|
let _icx = bcx0.insn_ctxt("closure::build_closure");
|
||||||
// If we need to, package up the iterator body to call
|
// 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;
|
let ccx = bcx.ccx(), tcx = ccx.tcx;
|
||||||
|
|
||||||
// Package up the captured upvars
|
// Package up the captured upvars
|
||||||
|
|
|
@ -192,7 +192,7 @@ pub fn trans_to_datum(bcx: block, expr: @ast::expr) -> DatumBlock {
|
||||||
}
|
}
|
||||||
Some(&@AutoAddEnv(*)) => {
|
Some(&@AutoAddEnv(*)) => {
|
||||||
let mut bcx = bcx;
|
let mut bcx = bcx;
|
||||||
let mut datum = unpack_datum!(bcx, {
|
let datum = unpack_datum!(bcx, {
|
||||||
trans_to_datum_unadjusted(bcx, expr)
|
trans_to_datum_unadjusted(bcx, expr)
|
||||||
});
|
});
|
||||||
add_env(bcx, expr, datum)
|
add_env(bcx, expr, datum)
|
||||||
|
@ -1187,7 +1187,7 @@ fn trans_rec_or_struct(bcx: block,
|
||||||
dest: Dest) -> block
|
dest: Dest) -> block
|
||||||
{
|
{
|
||||||
let _icx = bcx.insn_ctxt("trans_rec");
|
let _icx = bcx.insn_ctxt("trans_rec");
|
||||||
let mut bcx = bcx;
|
let bcx = bcx;
|
||||||
|
|
||||||
let ty = node_id_type(bcx, id);
|
let ty = node_id_type(bcx, id);
|
||||||
let tcx = bcx.tcx();
|
let tcx = bcx.tcx();
|
||||||
|
@ -1505,7 +1505,7 @@ fn trans_lazy_binop(bcx: block,
|
||||||
b: @ast::expr) -> DatumBlock {
|
b: @ast::expr) -> DatumBlock {
|
||||||
let _icx = bcx.insn_ctxt("trans_lazy_binop");
|
let _icx = bcx.insn_ctxt("trans_lazy_binop");
|
||||||
let binop_ty = expr_ty(bcx, binop_expr);
|
let binop_ty = expr_ty(bcx, binop_expr);
|
||||||
let mut bcx = bcx;
|
let bcx = bcx;
|
||||||
|
|
||||||
let Result {bcx: past_lhs, val: lhs} = {
|
let Result {bcx: past_lhs, val: lhs} = {
|
||||||
do base::with_scope_result(bcx, a.info(), ~"lhs") |bcx| {
|
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);
|
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) {
|
match *ccx.sess.str_of(item.ident) {
|
||||||
~"atomic_cxchg" => {
|
~"atomic_cxchg" => {
|
||||||
let old = AtomicCmpXchg(bcx,
|
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 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),
|
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 \
|
|| 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
|
// Set of used unsafe nodes (functions or blocks). Unsafe nodes not
|
||||||
// present in this set can be warned about.
|
// present in this set can be warned about.
|
||||||
used_unsafe: @mut HashSet<ast::node_id>,
|
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 {
|
pub enum tbox_flag {
|
||||||
|
@ -933,6 +938,7 @@ pub fn mk_ctxt(s: session::Session,
|
||||||
destructors: @mut HashSet::new(),
|
destructors: @mut HashSet::new(),
|
||||||
trait_impls: @mut HashMap::new(),
|
trait_impls: @mut HashMap::new(),
|
||||||
used_unsafe: @mut HashSet::new(),
|
used_unsafe: @mut HashSet::new(),
|
||||||
|
used_mut_nodes: @mut HashSet::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -180,7 +180,7 @@ pub struct Candidate {
|
||||||
|
|
||||||
pub impl<'self> LookupContext<'self> {
|
pub impl<'self> LookupContext<'self> {
|
||||||
fn do_lookup(&self, self_ty: ty::t) -> Option<method_map_entry> {
|
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.self_expr.span,
|
||||||
self_ty);
|
self_ty);
|
||||||
|
|
||||||
|
|
|
@ -1625,7 +1625,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
// block syntax lambdas; that is, lambdas without explicit
|
// block syntax lambdas; that is, lambdas without explicit
|
||||||
// sigils.
|
// sigils.
|
||||||
let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x));
|
let expected_sty = unpack_expected(fcx, expected, |x| Some(copy *x));
|
||||||
let mut error_happened = false;
|
let error_happened = false;
|
||||||
let (expected_sig,
|
let (expected_sig,
|
||||||
expected_purity,
|
expected_purity,
|
||||||
expected_sigil,
|
expected_sigil,
|
||||||
|
@ -1706,7 +1706,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
field: ast::ident,
|
field: ast::ident,
|
||||||
tys: &[@ast::Ty]) {
|
tys: &[@ast::Ty]) {
|
||||||
let tcx = fcx.ccx.tcx;
|
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,
|
let expr_t = structurally_resolved_type(fcx, expr.span,
|
||||||
fcx.expr_ty(base));
|
fcx.expr_ty(base));
|
||||||
let (base_t, derefs) = do_autoderef(fcx, expr.span, expr_t);
|
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) {
|
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_bot = false;
|
||||||
let mut saw_err = false;
|
let mut saw_err = false;
|
||||||
match stmt.node {
|
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);
|
ccx.tcx.enum_var_cache.insert(local_def(id), @variants);
|
||||||
|
|
||||||
// Check that it is possible to represent this enum:
|
// 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| {
|
if ty::type_structurally_contains(ccx.tcx, rty, |sty| {
|
||||||
match *sty {
|
match *sty {
|
||||||
ty::ty_enum(id, _) if id == did => {
|
ty::ty_enum(id, _) if id == did => {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
use core::prelude::*;
|
use core::prelude::*;
|
||||||
|
|
||||||
use middle::resolve::Impl;
|
use middle::resolve::Impl;
|
||||||
use middle::ty::{param_ty};
|
use middle::ty::param_ty;
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
use middle::typeck::check::{FnCtxt, impl_self_ty};
|
use middle::typeck::check::{FnCtxt, impl_self_ty};
|
||||||
use middle::typeck::check::{structurally_resolved_type};
|
use middle::typeck::check::{structurally_resolved_type};
|
||||||
|
|
|
@ -158,7 +158,7 @@ impl MethodRscope {
|
||||||
variance: Option<ty::region_variance>,
|
variance: Option<ty::region_variance>,
|
||||||
rcvr_generics: &ast::Generics)
|
rcvr_generics: &ast::Generics)
|
||||||
-> MethodRscope {
|
-> MethodRscope {
|
||||||
let mut region_param_names =
|
let region_param_names =
|
||||||
RegionParamNames::from_generics(rcvr_generics);
|
RegionParamNames::from_generics(rcvr_generics);
|
||||||
MethodRscope {
|
MethodRscope {
|
||||||
self_ty: self_ty,
|
self_ty: self_ty,
|
||||||
|
|
|
@ -891,7 +891,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_0_elements() {
|
fn test_0_elements() {
|
||||||
let mut act;
|
let mut act;
|
||||||
let mut exp;
|
let exp;
|
||||||
act = Bitv::new(0u, false);
|
act = Bitv::new(0u, false);
|
||||||
exp = vec::from_elem::<uint>(0u, 0u);
|
exp = vec::from_elem::<uint>(0u, 0u);
|
||||||
assert!(act.eq_vec(exp));
|
assert!(act.eq_vec(exp));
|
||||||
|
|
|
@ -113,7 +113,7 @@ pub impl<T> Deque<T> {
|
||||||
///
|
///
|
||||||
/// Fails if the deque is empty
|
/// Fails if the deque is empty
|
||||||
fn pop_front(&mut self) -> T {
|
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.lo = (self.lo + 1u) % self.elts.len();
|
||||||
self.nelts -= 1u;
|
self.nelts -= 1u;
|
||||||
result
|
result
|
||||||
|
@ -126,7 +126,7 @@ pub impl<T> Deque<T> {
|
||||||
if self.hi == 0u {
|
if self.hi == 0u {
|
||||||
self.hi = self.elts.len() - 1u;
|
self.hi = self.elts.len() - 1u;
|
||||||
} else { self.hi -= 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.elts[self.hi] = None;
|
||||||
self.nelts -= 1u;
|
self.nelts -= 1u;
|
||||||
result
|
result
|
||||||
|
@ -204,7 +204,7 @@ pub impl<T> Deque<T> {
|
||||||
///
|
///
|
||||||
/// Fails if the deque is empty
|
/// Fails if the deque is empty
|
||||||
fn pop_front(&mut self) -> T {
|
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.lo = (self.lo + 1u) % self.elts.len();
|
||||||
self.nelts -= 1u;
|
self.nelts -= 1u;
|
||||||
result
|
result
|
||||||
|
@ -217,7 +217,7 @@ pub impl<T> Deque<T> {
|
||||||
if self.hi == 0u {
|
if self.hi == 0u {
|
||||||
self.hi = self.elts.len() - 1u;
|
self.hi = self.elts.len() - 1u;
|
||||||
} else { self.hi -= 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.elts[self.hi] = None;
|
||||||
self.nelts -= 1u;
|
self.nelts -= 1u;
|
||||||
result
|
result
|
||||||
|
|
|
@ -220,7 +220,7 @@ pub impl<T> DList<T> {
|
||||||
* node. O(1).
|
* node. O(1).
|
||||||
*/
|
*/
|
||||||
fn push_head_n(@mut self, data: T) -> @mut DListNode<T> {
|
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);
|
self.add_head(nobe);
|
||||||
nobe.get()
|
nobe.get()
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ pub impl<T> DList<T> {
|
||||||
* node. O(1).
|
* node. O(1).
|
||||||
*/
|
*/
|
||||||
fn push_n(@mut self, data: T) -> @mut DListNode<T> {
|
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);
|
self.add_tail(nobe);
|
||||||
nobe.get()
|
nobe.get()
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ pub impl<T> DList<T> {
|
||||||
data: T,
|
data: T,
|
||||||
neighbour: @mut DListNode<T>
|
neighbour: @mut DListNode<T>
|
||||||
) -> @mut DListNode<T> {
|
) -> @mut DListNode<T> {
|
||||||
let mut nobe = DList::new_link(data);
|
let nobe = DList::new_link(data);
|
||||||
self.insert_left(nobe, neighbour);
|
self.insert_left(nobe, neighbour);
|
||||||
nobe.get()
|
nobe.get()
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,7 @@ pub impl<T> DList<T> {
|
||||||
data: T,
|
data: T,
|
||||||
neighbour: @mut DListNode<T>
|
neighbour: @mut DListNode<T>
|
||||||
) -> @mut DListNode<T> {
|
) -> @mut DListNode<T> {
|
||||||
let mut nobe = DList::new_link(data);
|
let nobe = DList::new_link(data);
|
||||||
self.insert_right(neighbour, nobe);
|
self.insert_right(neighbour, nobe);
|
||||||
nobe.get()
|
nobe.get()
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ impl<T: Copy + Num + Ord>
|
||||||
|
|
||||||
/// Put self into lowest terms, with denom > 0.
|
/// Put self into lowest terms, with denom > 0.
|
||||||
fn reduce(&mut self) {
|
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.numer /= g;
|
||||||
self.denom /= g;
|
self.denom /= g;
|
||||||
|
|
|
@ -838,8 +838,7 @@ pub mod node {
|
||||||
option::None => break,
|
option::None => break,
|
||||||
option::Some(x) => {
|
option::Some(x) => {
|
||||||
//FIXME (#2744): Replace with memcpy or something similar
|
//FIXME (#2744): Replace with memcpy or something similar
|
||||||
let mut local_buf: ~[u8] =
|
let local_buf: ~[u8] = cast::transmute(*x.content);
|
||||||
cast::transmute(*x.content);
|
|
||||||
let mut i = x.byte_offset;
|
let mut i = x.byte_offset;
|
||||||
while i < x.byte_len {
|
while i < x.byte_len {
|
||||||
buf[offset] = local_buf[i];
|
buf[offset] = local_buf[i];
|
||||||
|
@ -1156,7 +1155,7 @@ pub mod node {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty() -> T {
|
pub fn empty() -> T {
|
||||||
let mut stack : ~[@Node] = ~[];
|
let stack : ~[@Node] = ~[];
|
||||||
T { stack: stack, stackpos: -1 }
|
T { stack: stack, stackpos: -1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,7 @@ pub fn sha1() -> @Sha1 {
|
||||||
assert!((vec::len(st.h) == digest_buf_len));
|
assert!((vec::len(st.h) == digest_buf_len));
|
||||||
assert!((vec::uniq_len(st.work_buf) == work_buf_len));
|
assert!((vec::uniq_len(st.work_buf) == work_buf_len));
|
||||||
let mut t: int; // Loop counter
|
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
|
// Initialize the first 16 words of the vector w
|
||||||
t = 0;
|
t = 0;
|
||||||
|
@ -260,7 +260,7 @@ pub fn sha1() -> @Sha1 {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut st = Sha1State {
|
let st = Sha1State {
|
||||||
h: vec::from_elem(digest_buf_len, 0u32),
|
h: vec::from_elem(digest_buf_len, 0u32),
|
||||||
len_low: 0u32,
|
len_low: 0u32,
|
||||||
len_high: 0u32,
|
len_high: 0u32,
|
||||||
|
|
|
@ -239,7 +239,7 @@ fn binarysort<T:Copy + Ord>(array: &mut [T], start: uint) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
assert!(left == right);
|
assert!(left == right);
|
||||||
let mut n = start-left;
|
let n = start-left;
|
||||||
|
|
||||||
copy_vec(array, left+1, array, left, n);
|
copy_vec(array, left+1, array, left, n);
|
||||||
array[left] = pivot;
|
array[left] = pivot;
|
||||||
|
@ -416,7 +416,7 @@ impl<T:Copy + Ord> MergeState<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn merge_at(&mut self, n: uint, array: &mut [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!(size >= 2);
|
||||||
assert!(n == size-2 || n == size-3);
|
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);
|
let filtered_descs = filtered_tests.map(|t| t.desc);
|
||||||
callback(TeFiltered(filtered_descs));
|
callback(TeFiltered(filtered_descs));
|
||||||
|
|
||||||
let mut (filtered_tests,
|
let (filtered_tests, filtered_benchs) =
|
||||||
filtered_benchs) =
|
|
||||||
do vec::partition(filtered_tests) |e| {
|
do vec::partition(filtered_tests) |e| {
|
||||||
match e.testfn {
|
match e.testfn {
|
||||||
StaticTestFn(_) | DynTestFn(_) => true,
|
StaticTestFn(_) | DynTestFn(_) => true,
|
||||||
|
|
|
@ -147,7 +147,7 @@ pub fn empty_tm() -> Tm {
|
||||||
/// Returns the specified time in UTC
|
/// Returns the specified time in UTC
|
||||||
pub fn at_utc(clock: Timespec) -> Tm {
|
pub fn at_utc(clock: Timespec) -> Tm {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut Timespec { sec, nsec } = clock;
|
let Timespec { sec, nsec } = clock;
|
||||||
let mut tm = empty_tm();
|
let mut tm = empty_tm();
|
||||||
rustrt::rust_gmtime(sec, nsec, &mut tm);
|
rustrt::rust_gmtime(sec, nsec, &mut tm);
|
||||||
tm
|
tm
|
||||||
|
@ -162,7 +162,7 @@ pub fn now_utc() -> Tm {
|
||||||
/// Returns the specified time in the local timezone
|
/// Returns the specified time in the local timezone
|
||||||
pub fn at(clock: Timespec) -> Tm {
|
pub fn at(clock: Timespec) -> Tm {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut Timespec { sec, nsec } = clock;
|
let Timespec { sec, nsec } = clock;
|
||||||
let mut tm = empty_tm();
|
let mut tm = empty_tm();
|
||||||
rustrt::rust_localtime(sec, nsec, &mut tm);
|
rustrt::rust_localtime(sec, nsec, &mut tm);
|
||||||
tm
|
tm
|
||||||
|
|
|
@ -342,7 +342,7 @@ fn highlight_lines_internal(cm: @codemap::CodeMap,
|
||||||
while num > 0u { num /= 10u; digits += 1u; }
|
while num > 0u { num /= 10u; digits += 1u; }
|
||||||
|
|
||||||
// indent past |name:## | and the 0-offset column location
|
// 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 = ~"";
|
let mut s = ~"";
|
||||||
// Skip is the number of characters we need to skip because they are
|
// Skip is the number of characters we need to skip because they are
|
||||||
// part of the 'filename:line ' part of the previous line.
|
// 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 {
|
fn make_ty(cx: @ext_ctxt, sp: span, t: Ty) -> @ast::expr {
|
||||||
let mut rt_type;
|
let rt_type;
|
||||||
match t {
|
match t {
|
||||||
TyHex(c) => match c {
|
TyHex(c) => match c {
|
||||||
CaseUpper => rt_type = ~"TyHexUpper",
|
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
|
/* Translate each piece (portion of the fmt expression) by invoking the
|
||||||
corresponding function in core::unstable::extfmt. Each function takes a
|
corresponding function in core::unstable::extfmt. Each function takes a
|
||||||
buffer to insert data into along with the data being formatted. */
|
buffer to insert data into along with the data being formatted. */
|
||||||
|
let npieces = pieces.len();
|
||||||
do vec::consume(pieces) |i, pc| {
|
do vec::consume(pieces) |i, pc| {
|
||||||
match pc {
|
match pc {
|
||||||
/* Raw strings get appended via str::push_str */
|
/* 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);
|
let portion = mk_uniq_str(cx, fmt_sp, s);
|
||||||
|
|
||||||
/* If this is the first portion, then initialize the local
|
/* 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 {
|
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 {
|
} else {
|
||||||
let args = ~[mk_mut_addr_of(cx, fmt_sp, buf()), portion];
|
let args = ~[mk_mut_addr_of(cx, fmt_sp, buf()), portion];
|
||||||
let call = mk_call_global(cx,
|
let call = mk_call_global(cx,
|
||||||
|
|
|
@ -73,7 +73,7 @@ impl parser_attr for Parser {
|
||||||
self.expect(&token::LBRACKET);
|
self.expect(&token::LBRACKET);
|
||||||
let meta_item = self.parse_meta_item();
|
let meta_item = self.parse_meta_item();
|
||||||
self.expect(&token::RBRACKET);
|
self.expect(&token::RBRACKET);
|
||||||
let mut hi = self.span.hi;
|
let hi = self.span.hi;
|
||||||
return spanned(lo, hi, ast::attribute_ { style: style,
|
return spanned(lo, hi, ast::attribute_ { style: style,
|
||||||
value: meta_item,
|
value: meta_item,
|
||||||
is_sugared_doc: false });
|
is_sugared_doc: false });
|
||||||
|
@ -141,16 +141,16 @@ impl parser_attr for Parser {
|
||||||
token::EQ => {
|
token::EQ => {
|
||||||
self.bump();
|
self.bump();
|
||||||
let lit = self.parse_lit();
|
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))
|
@spanned(lo, hi, ast::meta_name_value(name, lit))
|
||||||
}
|
}
|
||||||
token::LPAREN => {
|
token::LPAREN => {
|
||||||
let inner_items = self.parse_meta_seq();
|
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))
|
@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))
|
@spanned(lo, hi, ast::meta_word(name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,7 +229,7 @@ fn read_block_comment(rdr: @mut StringReader,
|
||||||
debug!(">>> block comment");
|
debug!(">>> block comment");
|
||||||
let p = rdr.last_pos;
|
let p = rdr.last_pos;
|
||||||
let mut lines: ~[~str] = ~[];
|
let mut lines: ~[~str] = ~[];
|
||||||
let mut col: CharPos = rdr.col;
|
let col: CharPos = rdr.col;
|
||||||
bump(rdr);
|
bump(rdr);
|
||||||
bump(rdr);
|
bump(rdr);
|
||||||
|
|
||||||
|
|
|
@ -810,7 +810,7 @@ pub impl Parser {
|
||||||
// This version of parse arg doesn't necessarily require
|
// This version of parse arg doesn't necessarily require
|
||||||
// identifier names.
|
// identifier names.
|
||||||
fn parse_arg_general(&self, require_name: bool) -> arg {
|
fn parse_arg_general(&self, require_name: bool) -> arg {
|
||||||
let mut m;
|
let m;
|
||||||
let mut is_mutbl = false;
|
let mut is_mutbl = false;
|
||||||
let pat = if require_name || self.is_named_argument() {
|
let pat = if require_name || self.is_named_argument() {
|
||||||
m = self.parse_arg_mode();
|
m = self.parse_arg_mode();
|
||||||
|
@ -1154,7 +1154,7 @@ pub impl Parser {
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
let mut hi = self.span.hi;
|
let mut hi = self.span.hi;
|
||||||
|
|
||||||
let mut ex: expr_;
|
let ex: expr_;
|
||||||
|
|
||||||
if *self.token == token::LPAREN {
|
if *self.token == token::LPAREN {
|
||||||
self.bump();
|
self.bump();
|
||||||
|
@ -1629,9 +1629,9 @@ pub impl Parser {
|
||||||
// parse a prefix-operator expr
|
// parse a prefix-operator expr
|
||||||
fn parse_prefix_expr(&self) -> @expr {
|
fn parse_prefix_expr(&self) -> @expr {
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
let mut hi;
|
let hi;
|
||||||
|
|
||||||
let mut ex;
|
let ex;
|
||||||
match *self.token {
|
match *self.token {
|
||||||
token::NOT => {
|
token::NOT => {
|
||||||
self.bump();
|
self.bump();
|
||||||
|
@ -1781,7 +1781,7 @@ pub impl Parser {
|
||||||
token::BINOPEQ(op) => {
|
token::BINOPEQ(op) => {
|
||||||
self.bump();
|
self.bump();
|
||||||
let rhs = self.parse_expr();
|
let rhs = self.parse_expr();
|
||||||
let mut aop;
|
let aop;
|
||||||
match op {
|
match op {
|
||||||
token::PLUS => aop = add,
|
token::PLUS => aop = add,
|
||||||
token::MINUS => aop = subtract,
|
token::MINUS => aop = subtract,
|
||||||
|
@ -1956,7 +1956,7 @@ pub impl Parser {
|
||||||
let lo = self.last_span.lo;
|
let lo = self.last_span.lo;
|
||||||
let cond = self.parse_expr();
|
let cond = self.parse_expr();
|
||||||
let body = self.parse_block_no_value();
|
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));
|
return self.mk_expr(lo, hi, expr_while(cond, body));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1984,7 +1984,7 @@ pub impl Parser {
|
||||||
|
|
||||||
let lo = self.last_span.lo;
|
let lo = self.last_span.lo;
|
||||||
let body = self.parse_block_no_value();
|
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));
|
return self.mk_expr(lo, hi, expr_loop(body, opt_ident));
|
||||||
} else {
|
} else {
|
||||||
// This is a 'continue' expression
|
// This is a 'continue' expression
|
||||||
|
@ -2043,7 +2043,7 @@ pub impl Parser {
|
||||||
|
|
||||||
arms.push(ast::arm { pats: pats, guard: guard, body: blk });
|
arms.push(ast::arm { pats: pats, guard: guard, body: blk });
|
||||||
}
|
}
|
||||||
let mut hi = self.span.hi;
|
let hi = self.span.hi;
|
||||||
self.bump();
|
self.bump();
|
||||||
return self.mk_expr(lo, hi, expr_match(discriminant, arms));
|
return self.mk_expr(lo, hi, expr_match(discriminant, arms));
|
||||||
}
|
}
|
||||||
|
@ -2162,7 +2162,7 @@ pub impl Parser {
|
||||||
let hi1 = self.last_span.lo;
|
let hi1 = self.last_span.lo;
|
||||||
let fieldpath = ast_util::ident_to_path(mk_sp(lo1, hi1),
|
let fieldpath = ast_util::ident_to_path(mk_sp(lo1, hi1),
|
||||||
fieldname);
|
fieldname);
|
||||||
let mut subpat;
|
let subpat;
|
||||||
if *self.token == token::COLON {
|
if *self.token == token::COLON {
|
||||||
self.bump();
|
self.bump();
|
||||||
subpat = self.parse_pat(refutable);
|
subpat = self.parse_pat(refutable);
|
||||||
|
@ -2183,7 +2183,7 @@ pub impl Parser {
|
||||||
|
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
let mut hi = self.span.hi;
|
let mut hi = self.span.hi;
|
||||||
let mut pat;
|
let pat;
|
||||||
match *self.token {
|
match *self.token {
|
||||||
token::UNDERSCORE => { self.bump(); pat = pat_wild; }
|
token::UNDERSCORE => { self.bump(); pat = pat_wild; }
|
||||||
token::AT => {
|
token::AT => {
|
||||||
|
@ -2534,7 +2534,7 @@ pub impl Parser {
|
||||||
match self.parse_item_or_view_item(/*bad*/ copy item_attrs,
|
match self.parse_item_or_view_item(/*bad*/ copy item_attrs,
|
||||||
true, false, false) {
|
true, false, false) {
|
||||||
iovi_item(i) => {
|
iovi_item(i) => {
|
||||||
let mut hi = i.span.hi;
|
let hi = i.span.hi;
|
||||||
let decl = @spanned(lo, hi, decl_item(i));
|
let decl = @spanned(lo, hi, decl_item(i));
|
||||||
return @spanned(lo, hi, stmt_decl(decl, self.get_id()));
|
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();
|
self.bump();
|
||||||
let bloc = ast::blk_ {
|
let bloc = ast::blk_ {
|
||||||
view_items: view_items,
|
view_items: view_items,
|
||||||
|
@ -3590,7 +3590,7 @@ pub impl Parser {
|
||||||
let purity = self.parse_fn_purity();
|
let purity = self.parse_fn_purity();
|
||||||
let (ident, generics) = self.parse_fn_header();
|
let (ident, generics) = self.parse_fn_header();
|
||||||
let decl = self.parse_fn_decl(|p| p.parse_arg());
|
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);
|
self.expect(&token::SEMI);
|
||||||
@ast::foreign_item { ident: ident,
|
@ast::foreign_item { ident: ident,
|
||||||
attrs: attrs,
|
attrs: attrs,
|
||||||
|
@ -3798,7 +3798,7 @@ pub impl Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.bump();
|
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;
|
let (d_body, d_attrs, d_s) = copy *dtor;
|
||||||
codemap::spanned { node: ast::struct_dtor_ { id: self.get_id(),
|
codemap::spanned { node: ast::struct_dtor_ { id: self.get_id(),
|
||||||
attrs: d_attrs,
|
attrs: d_attrs,
|
||||||
|
|
|
@ -146,9 +146,9 @@ pub fn mk_printer(out: @io::Writer, linewidth: uint) -> @mut Printer {
|
||||||
// fall behind.
|
// fall behind.
|
||||||
let n: uint = 3 * linewidth;
|
let n: uint = 3 * linewidth;
|
||||||
debug!("mk_printer %u", linewidth);
|
debug!("mk_printer %u", linewidth);
|
||||||
let mut token: ~[token] = vec::from_elem(n, EOF);
|
let token: ~[token] = vec::from_elem(n, EOF);
|
||||||
let mut size: ~[int] = vec::from_elem(n, 0);
|
let size: ~[int] = vec::from_elem(n, 0);
|
||||||
let mut scan_stack: ~[uint] = vec::from_elem(n, 0u);
|
let scan_stack: ~[uint] = vec::from_elem(n, 0u);
|
||||||
@mut Printer {
|
@mut Printer {
|
||||||
out: @out,
|
out: @out,
|
||||||
buf_len: n,
|
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,
|
pub fn maybe_print_trailing_comment(s: @ps, span: codemap::span,
|
||||||
next_pos: Option<BytePos>) {
|
next_pos: Option<BytePos>) {
|
||||||
let mut cm;
|
let cm;
|
||||||
match s.cm { Some(ccm) => cm = ccm, _ => return }
|
match s.cm { Some(ccm) => cm = ccm, _ => return }
|
||||||
match next_comment(s) {
|
match next_comment(s) {
|
||||||
Some(ref cmnt) => {
|
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