diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 1cb10d59e59..8ec0674f74f 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -428,7 +428,7 @@ fn len_and_str(s: &str) -> ~str { } fn len_and_str_lit(l: ast::lit) -> ~str { - len_and_str(pprust::lit_to_str(@l)) + len_and_str(pprust::lit_to_str(&l)) } let cmh_items = attr::sort_meta_items(cmh_items); diff --git a/src/librustc/front/test.rs b/src/librustc/front/test.rs index cf8dbfdcad6..192249d6435 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -330,7 +330,7 @@ pub fn main() { }; debug!("Synthetic test module:\n{}\n", - pprust::item_to_str(@item.clone(), cx.sess.intr())); + pprust::item_to_str(&item, cx.sess.intr())); return @item; } diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 6d0816de433..2a69b8226ae 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -1028,27 +1028,47 @@ fn check_unused_mut_pat(cx: &Context, p: &ast::Pat) { } } +enum Allocation { + VectorAllocation, + BoxAllocation +} + fn check_unnecessary_allocation(cx: &Context, e: &ast::Expr) { - // Warn if string and vector literals with sigils are immediately borrowed. - // Those can have the sigil removed. - match e.node { + // Warn if string and vector literals with sigils, or boxing expressions, + // are immediately borrowed. + let allocation = match e.node { ast::ExprVstore(e2, ast::ExprVstoreUniq) | ast::ExprVstore(e2, ast::ExprVstoreBox) => { match e2.node { ast::ExprLit(@codemap::Spanned{node: ast::lit_str(..), ..}) | - ast::ExprVec(..) => {} + ast::ExprVec(..) => VectorAllocation, _ => return } } + ast::ExprUnary(_, ast::UnUniq, _) | + ast::ExprUnary(_, ast::UnBox(..), _) => BoxAllocation, _ => return - } + }; + + let report = |msg| { + cx.span_lint(unnecessary_allocation, e.span, msg); + }; match cx.tcx.adjustments.find_copy(&e.id) { - Some(@ty::AutoDerefRef(ty::AutoDerefRef { - autoref: Some(ty::AutoBorrowVec(..)), .. })) => { - cx.span_lint(unnecessary_allocation, e.span, - "unnecessary allocation, the sigil can be removed"); + Some(@ty::AutoDerefRef(ty::AutoDerefRef { autoref, .. })) => { + match (allocation, autoref) { + (VectorAllocation, Some(ty::AutoBorrowVec(..))) => { + report("unnecessary allocation, the sigil can be removed"); + } + (BoxAllocation, Some(ty::AutoPtr(_, ast::MutImmutable))) => { + report("unnecessary allocation, use & instead"); + } + (BoxAllocation, Some(ty::AutoPtr(_, ast::MutMutable))) => { + report("unnecessary allocation, use &mut instead"); + } + _ => () + } } _ => () diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs index 0c6eb6a94a8..451e6683f0c 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -119,28 +119,28 @@ fn to_source(&self) -> @str { impl<'self> ToSource for &'self str { fn to_source(&self) -> @str { let lit = dummy_spanned(ast::lit_str(self.to_managed(), ast::CookedStr)); - pprust::lit_to_str(@lit).to_managed() + pprust::lit_to_str(&lit).to_managed() } } impl ToSource for int { fn to_source(&self) -> @str { let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i)); - pprust::lit_to_str(@lit).to_managed() + pprust::lit_to_str(&lit).to_managed() } } impl ToSource for i8 { fn to_source(&self) -> @str { let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i8)); - pprust::lit_to_str(@lit).to_managed() + pprust::lit_to_str(&lit).to_managed() } } impl ToSource for i16 { fn to_source(&self) -> @str { let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i16)); - pprust::lit_to_str(@lit).to_managed() + pprust::lit_to_str(&lit).to_managed() } } @@ -148,49 +148,49 @@ fn to_source(&self) -> @str { impl ToSource for i32 { fn to_source(&self) -> @str { let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i32)); - pprust::lit_to_str(@lit).to_managed() + pprust::lit_to_str(&lit).to_managed() } } impl ToSource for i64 { fn to_source(&self) -> @str { let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i64)); - pprust::lit_to_str(@lit).to_managed() + pprust::lit_to_str(&lit).to_managed() } } impl ToSource for uint { fn to_source(&self) -> @str { let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u)); - pprust::lit_to_str(@lit).to_managed() + pprust::lit_to_str(&lit).to_managed() } } impl ToSource for u8 { fn to_source(&self) -> @str { let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u8)); - pprust::lit_to_str(@lit).to_managed() + pprust::lit_to_str(&lit).to_managed() } } impl ToSource for u16 { fn to_source(&self) -> @str { let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u16)); - pprust::lit_to_str(@lit).to_managed() + pprust::lit_to_str(&lit).to_managed() } } impl ToSource for u32 { fn to_source(&self) -> @str { let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u32)); - pprust::lit_to_str(@lit).to_managed() + pprust::lit_to_str(&lit).to_managed() } } impl ToSource for u64 { fn to_source(&self) -> @str { let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u64)); - pprust::lit_to_str(@lit).to_managed() + pprust::lit_to_str(&lit).to_managed() } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 3c6fa86485d..ea382e1cefe 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1902,7 +1902,7 @@ pub fn print_meta_item(s: @ps, item: &ast::MetaItem) { ast::MetaNameValue(name, value) => { word_space(s, name); word_space(s, "="); - print_literal(s, @value); + print_literal(s, &value); } ast::MetaList(name, ref items) => { word(s.s, name); diff --git a/src/test/compile-fail/lint-allocation.rs b/src/test/compile-fail/lint-allocation.rs new file mode 100644 index 00000000000..608cb7fd4a5 --- /dev/null +++ b/src/test/compile-fail/lint-allocation.rs @@ -0,0 +1,19 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[deny(unnecessary_allocation)]; + +fn f(_: &int) {} +fn g(_: &mut int) {} + +fn main() { + f(~1); //~ ERROR unnecessary allocation, use & instead + g(~1); //~ ERROR unnecessary allocation, use &mut instead +}