From 945c027768d96473a33f9914eea21326f82836bc Mon Sep 17 00:00:00 2001 From: mcarton Date: Thu, 17 Nov 2016 19:44:18 +0100 Subject: [PATCH] Handle closure with single expression blocks --- clippy_lints/src/map_clone.rs | 3 ++- clippy_lints/src/utils/mod.rs | 19 +++++++++++++++++++ tests/compile-fail/map_clone.rs | 6 ++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/map_clone.rs b/clippy_lints/src/map_clone.rs index 17975ed3768..674f2bbc11a 100644 --- a/clippy_lints/src/map_clone.rs +++ b/clippy_lints/src/map_clone.rs @@ -1,7 +1,7 @@ use rustc::lint::*; use rustc::hir::*; use syntax::ast; -use utils::{is_adjusted, match_path, match_trait_method, match_type, paths, snippet, +use utils::{is_adjusted, match_path, match_trait_method, match_type, remove_blocks, paths, snippet, span_help_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth}; /// **What it does:** Checks for mapping `clone()` over an iterator. @@ -31,6 +31,7 @@ impl LateLintPass for Pass { if name.node.as_str() == "map" && args.len() == 2 { match args[1].node { ExprClosure(_, ref decl, ref closure_expr, _) => { + let closure_expr = remove_blocks(closure_expr); if_let_chain! {[ // nothing special in the argument, besides reference bindings // (e.g. .map(|&x| x) ) diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index f273233b947..122ba9cdc1a 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -773,3 +773,22 @@ pub fn is_refutable(cx: &LateContext, pat: &Pat) -> bool { pub fn is_automatically_derived(attrs: &[ast::Attribute]) -> bool { attr::contains_name(attrs, "automatically_derived") } + +/// Remove blocks around an expression. +/// +/// Ie. `x`, `{ x }` and `{{{{ x }}}}` all give `x`. `{ x; y }` and `{}` return themselves. +pub fn remove_blocks(expr: &Expr) -> &Expr { + if let ExprBlock(ref block) = expr.node { + if block.stmts.is_empty() { + if let Some(ref expr) = block.expr { + remove_blocks(expr) + } else { + expr + } + } else { + expr + } + } else { + expr + } +} diff --git a/tests/compile-fail/map_clone.rs b/tests/compile-fail/map_clone.rs index bd630211f19..b4f97ae8e6e 100644 --- a/tests/compile-fail/map_clone.rs +++ b/tests/compile-fail/map_clone.rs @@ -15,6 +15,12 @@ fn map_clone_iter() { //~^ HELP try x.iter().map(|y| *y); //~ ERROR you seem to be using .map() //~^ HELP try + x.iter().map(|y| { y.clone() }); //~ ERROR you seem to be using .map() + //~^ HELP try + x.iter().map(|&y| { y }); //~ ERROR you seem to be using .map() + //~^ HELP try + x.iter().map(|y| { *y }); //~ ERROR you seem to be using .map() + //~^ HELP try x.iter().map(Clone::clone); //~ ERROR you seem to be using .map() //~^ HELP try }