Extend allocation lint for boxing expressions
This commit is contained in:
parent
e5f2021202
commit
3b14f25868
@ -428,7 +428,7 @@ fn len_and_str(s: &str) -> ~str {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn len_and_str_lit(l: ast::lit) -> ~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);
|
let cmh_items = attr::sort_meta_items(cmh_items);
|
||||||
|
@ -330,7 +330,7 @@ pub fn main() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
debug!("Synthetic test module:\n{}\n",
|
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;
|
return @item;
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
fn check_unnecessary_allocation(cx: &Context, e: &ast::Expr) {
|
||||||
// Warn if string and vector literals with sigils are immediately borrowed.
|
// Warn if string and vector literals with sigils, or boxing expressions,
|
||||||
// Those can have the sigil removed.
|
// are immediately borrowed.
|
||||||
match e.node {
|
let allocation = match e.node {
|
||||||
ast::ExprVstore(e2, ast::ExprVstoreUniq) |
|
ast::ExprVstore(e2, ast::ExprVstoreUniq) |
|
||||||
ast::ExprVstore(e2, ast::ExprVstoreBox) => {
|
ast::ExprVstore(e2, ast::ExprVstoreBox) => {
|
||||||
match e2.node {
|
match e2.node {
|
||||||
ast::ExprLit(@codemap::Spanned{node: ast::lit_str(..), ..}) |
|
ast::ExprLit(@codemap::Spanned{node: ast::lit_str(..), ..}) |
|
||||||
ast::ExprVec(..) => {}
|
ast::ExprVec(..) => VectorAllocation,
|
||||||
_ => return
|
_ => return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ast::ExprUnary(_, ast::UnUniq, _) |
|
||||||
|
ast::ExprUnary(_, ast::UnBox(..), _) => BoxAllocation,
|
||||||
|
|
||||||
_ => return
|
_ => return
|
||||||
}
|
};
|
||||||
|
|
||||||
|
let report = |msg| {
|
||||||
|
cx.span_lint(unnecessary_allocation, e.span, msg);
|
||||||
|
};
|
||||||
|
|
||||||
match cx.tcx.adjustments.find_copy(&e.id) {
|
match cx.tcx.adjustments.find_copy(&e.id) {
|
||||||
Some(@ty::AutoDerefRef(ty::AutoDerefRef {
|
Some(@ty::AutoDerefRef(ty::AutoDerefRef { autoref, .. })) => {
|
||||||
autoref: Some(ty::AutoBorrowVec(..)), .. })) => {
|
match (allocation, autoref) {
|
||||||
cx.span_lint(unnecessary_allocation, e.span,
|
(VectorAllocation, Some(ty::AutoBorrowVec(..))) => {
|
||||||
"unnecessary allocation, the sigil can be removed");
|
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");
|
||||||
|
}
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => ()
|
_ => ()
|
||||||
|
@ -119,28 +119,28 @@ fn to_source(&self) -> @str {
|
|||||||
impl<'self> ToSource for &'self str {
|
impl<'self> ToSource for &'self str {
|
||||||
fn to_source(&self) -> @str {
|
fn to_source(&self) -> @str {
|
||||||
let lit = dummy_spanned(ast::lit_str(self.to_managed(), ast::CookedStr));
|
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 {
|
impl ToSource for int {
|
||||||
fn to_source(&self) -> @str {
|
fn to_source(&self) -> @str {
|
||||||
let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i));
|
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 {
|
impl ToSource for i8 {
|
||||||
fn to_source(&self) -> @str {
|
fn to_source(&self) -> @str {
|
||||||
let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i8));
|
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 {
|
impl ToSource for i16 {
|
||||||
fn to_source(&self) -> @str {
|
fn to_source(&self) -> @str {
|
||||||
let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i16));
|
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 {
|
impl ToSource for i32 {
|
||||||
fn to_source(&self) -> @str {
|
fn to_source(&self) -> @str {
|
||||||
let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i32));
|
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 {
|
impl ToSource for i64 {
|
||||||
fn to_source(&self) -> @str {
|
fn to_source(&self) -> @str {
|
||||||
let lit = dummy_spanned(ast::lit_int(*self as i64, ast::ty_i64));
|
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 {
|
impl ToSource for uint {
|
||||||
fn to_source(&self) -> @str {
|
fn to_source(&self) -> @str {
|
||||||
let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u));
|
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 {
|
impl ToSource for u8 {
|
||||||
fn to_source(&self) -> @str {
|
fn to_source(&self) -> @str {
|
||||||
let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u8));
|
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 {
|
impl ToSource for u16 {
|
||||||
fn to_source(&self) -> @str {
|
fn to_source(&self) -> @str {
|
||||||
let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u16));
|
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 {
|
impl ToSource for u32 {
|
||||||
fn to_source(&self) -> @str {
|
fn to_source(&self) -> @str {
|
||||||
let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u32));
|
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 {
|
impl ToSource for u64 {
|
||||||
fn to_source(&self) -> @str {
|
fn to_source(&self) -> @str {
|
||||||
let lit = dummy_spanned(ast::lit_uint(*self as u64, ast::ty_u64));
|
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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1902,7 +1902,7 @@ pub fn print_meta_item(s: @ps, item: &ast::MetaItem) {
|
|||||||
ast::MetaNameValue(name, value) => {
|
ast::MetaNameValue(name, value) => {
|
||||||
word_space(s, name);
|
word_space(s, name);
|
||||||
word_space(s, "=");
|
word_space(s, "=");
|
||||||
print_literal(s, @value);
|
print_literal(s, &value);
|
||||||
}
|
}
|
||||||
ast::MetaList(name, ref items) => {
|
ast::MetaList(name, ref items) => {
|
||||||
word(s.s, name);
|
word(s.s, name);
|
||||||
|
19
src/test/compile-fail/lint-allocation.rs
Normal file
19
src/test/compile-fail/lint-allocation.rs
Normal file
@ -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 <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.
|
||||||
|
|
||||||
|
#[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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user