Merge pull request #523 from sanxiyn/escape-arg

Extend escape analysis to arguments
This commit is contained in:
llogiq 2016-01-16 00:03:58 +01:00
commit 840d87022e
3 changed files with 21 additions and 3 deletions

View File

@ -31,6 +31,13 @@ pub struct EscapePass;
/// ```
declare_lint!(pub BOXED_LOCAL, Warn, "using Box<T> where unnecessary");
fn is_box(ty: ty::Ty) -> bool {
match ty.sty {
ty::TyBox(..) => true,
_ => false
}
}
struct EscapeDelegate<'a, 'tcx: 'a> {
cx: &'a LateContext<'a, 'tcx>,
set: NodeSet,
@ -77,6 +84,12 @@ impl<'a, 'tcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
}
fn matched_pat(&mut self, _: &Pat, _: cmt<'tcx>, _: MatchMode) {}
fn consume_pat(&mut self, consume_pat: &Pat, cmt: cmt<'tcx>, _: ConsumeMode) {
if self.cx.tcx.map.is_argument(consume_pat.id) {
if is_box(cmt.ty) {
self.set.insert(consume_pat.id);
}
return;
}
if let Categorization::Rvalue(..) = cmt.cat {
if let Some(Node::NodeStmt(st)) = self.cx
.tcx
@ -86,7 +99,7 @@ impl<'a, 'tcx: 'a> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
if let DeclLocal(ref loc) = decl.node {
if let Some(ref ex) = loc.init {
if let ExprBox(..) = ex.node {
if let ty::TyBox(..) = cmt.ty.sty {
if is_box(cmt.ty) {
// let x = box (...)
self.set.insert(consume_pat.id);
}

View File

@ -1,7 +1,8 @@
#![feature(plugin)]
#![plugin(clippy)]
#![deny(clippy)]
#![allow(boxed_local)]
macro_rules! boxit {
($init:expr, $x:ty) => {

View File

@ -19,6 +19,10 @@ fn warn_call() {
x.foo();
}
fn warn_arg(x: Box<A>) { //~ ERROR local variable
x.foo();
}
fn warn_rename_call() {
let x = box A;
@ -78,4 +82,4 @@ fn warn_match() {
match &x { // not moved
ref y => ()
}
}
}