From 9bd4e5469e1ecb7d98602ba1d805872faa8bf2c9 Mon Sep 17 00:00:00 2001 From: Ryan Cumming Date: Mon, 8 Oct 2018 06:20:32 +1100 Subject: [PATCH] Don't suggest cloned() for map Box deref Boxes are a bit magic in that they need to use `*` to get an owned value out of the box. They implement `Deref` but that only returns a reference. This means an easy way to convert an `Option>` to an `` is: ``` box_option.map(|b| *b) ``` However, since b36bb0a6 the `map_clone` lint is detecting this as an attempt to copy the box. Fix by excluding boxes completely from the deref part of this lint. Fixes #3274 --- clippy_lints/src/map_clone.rs | 2 +- tests/ui/map_clone.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index c2bfcf18280..b2c08e6ae8c 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -79,7 +79,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { lint(cx, e.span, args[0].span, name, closure_expr); }, hir::PatKind::Binding(hir::BindingAnnotation::Unannotated, _, name, None) => match closure_expr.node { - hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner) => lint(cx, e.span, args[0].span, name, inner), + hir::ExprKind::Unary(hir::UnOp::UnDeref, ref inner) if !cx.tables.expr_ty(inner).is_box() => lint(cx, e.span, args[0].span, name, inner), hir::ExprKind::MethodCall(ref method, _, ref obj) => if method.ident.as_str() == "clone" && match_trait_method(cx, closure_expr, &paths::CLONE_TRAIT) { lint(cx, e.span, args[0].span, name, &obj[0]); } diff --git a/tests/ui/map_clone.rs b/tests/ui/map_clone.rs index 8a410737f83..90611023f75 100644 --- a/tests/ui/map_clone.rs +++ b/tests/ui/map_clone.rs @@ -16,4 +16,5 @@ fn main() { let _: Vec = vec![5_i8; 6].iter().map(|x| *x).collect(); let _: Vec = vec![String::new()].iter().map(|x| x.clone()).collect(); let _: Vec = vec![42, 43].iter().map(|&x| x).collect(); + let _: Option = Some(Box::new(16)).map(|b| *b); }