diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index c37efbd6e49d..52799ffbb454 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -4,6 +4,7 @@ use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use rustc::middle::expr_use_visitor::*; use rustc::middle::mem_categorization::{cmt_, Categorization}; use rustc::ty::layout::LayoutOf; +use rustc::ty::query::TyCtxtAt; use rustc::ty::{self, Ty}; use rustc::util::nodemap::HirIdSet; use rustc::{declare_tool_lint, impl_lint_pass}; @@ -142,7 +143,10 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { if let StmtKind::Local(ref loc) = st.node { if let Some(ref ex) = loc.init { if let ExprKind::Box(..) = ex.node { - if is_non_trait_box(cmt.ty) && !self.is_large_box(cmt.ty) { + if is_non_trait_box(cmt.ty) + && !self.is_large_box(cmt.ty) + && !self.is_unsized_box(cmt.ty, cmt.span) + { // let x = box (...) self.set.insert(consume_pat.hir_id); } @@ -205,4 +209,13 @@ impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> { false } } + + fn is_unsized_box(&self, ty: Ty<'tcx>, span: Span) -> bool { + if !ty.is_box() { + return false; + } + + !ty.boxed_ty() + .is_sized(TyCtxtAt { tcx: self.cx.tcx, span }, self.cx.param_env) + } } diff --git a/tests/ui/escape_analysis.rs b/tests/ui/escape_analysis.rs index 78d332c7a31c..0c7641c30d82 100644 --- a/tests/ui/escape_analysis.rs +++ b/tests/ui/escape_analysis.rs @@ -109,6 +109,14 @@ fn nowarn_large_array() { } } +fn nowarn_non_sized() { + let x: Box<[u32]> = box [1; 10000]; + match &x { + // not moved + ref y => (), + } +} + /// ICE regression test pub trait Foo { type Item; diff --git a/tests/ui/escape_analysis.stderr b/tests/ui/escape_analysis.stderr index 3944acd87f28..a214f418c718 100644 --- a/tests/ui/escape_analysis.stderr +++ b/tests/ui/escape_analysis.stderr @@ -7,13 +7,13 @@ LL | fn warn_arg(x: Box) { = note: `-D clippy::boxed-local` implied by `-D warnings` error: local variable doesn't need to be boxed here - --> $DIR/escape_analysis.rs:125:12 + --> $DIR/escape_analysis.rs:133:12 | LL | pub fn new(_needs_name: Box>) -> () {} | ^^^^^^^^^^^ error: local variable doesn't need to be boxed here - --> $DIR/escape_analysis.rs:165:23 + --> $DIR/escape_analysis.rs:173:23 | LL | fn closure_borrow(x: Box) { | ^