From 3b14f25868dd0423b03b41ff413470866f774280 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Mon, 9 Dec 2013 23:18:24 +0900 Subject: [PATCH] Extend allocation lint for boxing expressions --- src/librustc/back/link.rs | 2 +- src/librustc/front/test.rs | 2 +- src/librustc/middle/lint.rs | 38 ++++++++++++++++++------ src/libsyntax/ext/quote.rs | 22 +++++++------- src/libsyntax/print/pprust.rs | 2 +- src/test/compile-fail/lint-allocation.rs | 19 ++++++++++++ 6 files changed, 62 insertions(+), 23 deletions(-) create mode 100644 src/test/compile-fail/lint-allocation.rs diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 1cb10d59e59c9..8ec0674f74f69 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -428,7 +428,7 @@ pub fn build_link_meta(sess: Session, } 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 cf8dbfdcad6a5..192249d6435d5 100644 --- a/src/librustc/front/test.rs +++ b/src/librustc/front/test.rs @@ -330,7 +330,7 @@ fn mk_test_module(cx: &TestCtxt) -> @ast::item { }; 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 6d0816de433ee..2a69b8226ae91 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 0c6eb6a94a8be..451e6683f0cd3 100644 --- a/src/libsyntax/ext/quote.rs +++ b/src/libsyntax/ext/quote.rs @@ -119,28 +119,28 @@ pub mod rt { 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 @@ pub mod rt { 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 3c6fa86485d21..ea382e1cefef8 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 0000000000000..608cb7fd4a53e --- /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 +}