diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs index 2c6bfae6efe1..d15a619ef9f0 100644 --- a/clippy_lints/src/escape.rs +++ b/clippy_lints/src/escape.rs @@ -102,8 +102,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> { fn consume(&mut self, _: HirId, _: Span, cmt: &cmt_<'tcx>, mode: ConsumeMode) { if let Categorization::Local(lid) = cmt.cat { - if let Move(DirectRefMove) = mode { - // Moved out or in. Clearly can't be localized. + if let Move(DirectRefMove) | Move(CaptureMove) = mode { + // moved out or in. clearly can't be localized self.set.remove(&lid); } } diff --git a/tests/ui/escape_analysis.rs b/tests/ui/escape_analysis.rs index f582596eb56a..e3f78182fd13 100644 --- a/tests/ui/escape_analysis.rs +++ b/tests/ui/escape_analysis.rs @@ -148,3 +148,23 @@ trait MyTrait { impl MyTrait for Box { fn do_sth(self) {} } + +// Issue #3739 - capture in closures +mod issue_3739 { + use super::A; + + fn consume(_: T) {} + fn borrow(_: &T) {} + + fn closure_consume(x: Box) { + let _ = move || { + consume(x); + }; + } + + fn closure_borrow(x: Box) { + let _ = || { + borrow(&x); + }; + } +} diff --git a/tests/ui/escape_analysis.stderr b/tests/ui/escape_analysis.stderr index 8af211f8a1a9..3944acd87f28 100644 --- a/tests/ui/escape_analysis.stderr +++ b/tests/ui/escape_analysis.stderr @@ -12,5 +12,11 @@ error: local variable doesn't need to be boxed here LL | pub fn new(_needs_name: Box>) -> () {} | ^^^^^^^^^^^ -error: aborting due to 2 previous errors +error: local variable doesn't need to be boxed here + --> $DIR/escape_analysis.rs:165:23 + | +LL | fn closure_borrow(x: Box) { + | ^ + +error: aborting due to 3 previous errors