From 07830c44af2bc95332b36b51434bd73300c33fc1 Mon Sep 17 00:00:00 2001 From: Seo Sanghyeon Date: Mon, 28 Dec 2015 23:12:57 +0900 Subject: [PATCH] Extend escape analysis to arguments --- src/escape.rs | 15 ++++++++++++++- tests/compile-fail/box_vec.rs | 3 ++- tests/compile-fail/escape_analysis.rs | 6 +++++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/escape.rs b/src/escape.rs index 63894cda9be..9ee9d7ff344 100644 --- a/src/escape.rs +++ b/src/escape.rs @@ -31,6 +31,13 @@ pub struct EscapePass; /// ``` declare_lint!(pub BOXED_LOCAL, Warn, "using Box 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); } diff --git a/tests/compile-fail/box_vec.rs b/tests/compile-fail/box_vec.rs index 58e780f190c..65275923dc5 100644 --- a/tests/compile-fail/box_vec.rs +++ b/tests/compile-fail/box_vec.rs @@ -1,7 +1,8 @@ #![feature(plugin)] - #![plugin(clippy)] + #![deny(clippy)] +#![allow(boxed_local)] pub fn test(foo: Box>) { //~ ERROR you seem to be trying to use `Box>` println!("{:?}", foo.get(0)) diff --git a/tests/compile-fail/escape_analysis.rs b/tests/compile-fail/escape_analysis.rs index 3782cb96da5..28154d9414e 100644 --- a/tests/compile-fail/escape_analysis.rs +++ b/tests/compile-fail/escape_analysis.rs @@ -19,6 +19,10 @@ fn warn_call() { x.foo(); } +fn warn_arg(x: Box) { //~ 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 => () } -} \ No newline at end of file +}