Extend escape analysis to arguments

This commit is contained in:
Seo Sanghyeon 2015-12-28 23:12:57 +09:00
parent ee236dac46
commit 07830c44af
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,
@ -87,6 +94,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
@ -96,7 +109,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)]
pub fn test(foo: Box<Vec<bool>>) { //~ ERROR you seem to be trying to use `Box<Vec<T>>`
println!("{:?}", foo.get(0))

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 => ()
}
}
}