diff --git a/src/escape.rs b/src/escape.rs index 079fdcf09..8ef64aee8 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, @@ -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); } diff --git a/tests/compile-fail/box_vec.rs b/tests/compile-fail/box_vec.rs index 4fd98cd52..044e7dffa 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)] macro_rules! boxit { ($init:expr, $x:ty) => { diff --git a/tests/compile-fail/escape_analysis.rs b/tests/compile-fail/escape_analysis.rs index 3782cb96d..28154d941 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 +}