Skip to content

Commit 945c027

Browse files
committed
Handle closure with single expression blocks
1 parent 19c5f53 commit 945c027

File tree

3 files changed

+27
-1
lines changed

3 files changed

+27
-1
lines changed

clippy_lints/src/map_clone.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc::lint::*;
22
use rustc::hir::*;
33
use syntax::ast;
4-
use utils::{is_adjusted, match_path, match_trait_method, match_type, paths, snippet,
4+
use utils::{is_adjusted, match_path, match_trait_method, match_type, remove_blocks, paths, snippet,
55
span_help_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth};
66

77
/// **What it does:** Checks for mapping `clone()` over an iterator.
@@ -31,6 +31,7 @@ impl LateLintPass for Pass {
3131
if name.node.as_str() == "map" && args.len() == 2 {
3232
match args[1].node {
3333
ExprClosure(_, ref decl, ref closure_expr, _) => {
34+
let closure_expr = remove_blocks(closure_expr);
3435
if_let_chain! {[
3536
// nothing special in the argument, besides reference bindings
3637
// (e.g. .map(|&x| x) )

clippy_lints/src/utils/mod.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,3 +773,22 @@ pub fn is_refutable(cx: &LateContext, pat: &Pat) -> bool {
773773
pub fn is_automatically_derived(attrs: &[ast::Attribute]) -> bool {
774774
attr::contains_name(attrs, "automatically_derived")
775775
}
776+
777+
/// Remove blocks around an expression.
778+
///
779+
/// Ie. `x`, `{ x }` and `{{{{ x }}}}` all give `x`. `{ x; y }` and `{}` return themselves.
780+
pub fn remove_blocks(expr: &Expr) -> &Expr {
781+
if let ExprBlock(ref block) = expr.node {
782+
if block.stmts.is_empty() {
783+
if let Some(ref expr) = block.expr {
784+
remove_blocks(expr)
785+
} else {
786+
expr
787+
}
788+
} else {
789+
expr
790+
}
791+
} else {
792+
expr
793+
}
794+
}

tests/compile-fail/map_clone.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ fn map_clone_iter() {
1515
//~^ HELP try
1616
x.iter().map(|y| *y); //~ ERROR you seem to be using .map()
1717
//~^ HELP try
18+
x.iter().map(|y| { y.clone() }); //~ ERROR you seem to be using .map()
19+
//~^ HELP try
20+
x.iter().map(|&y| { y }); //~ ERROR you seem to be using .map()
21+
//~^ HELP try
22+
x.iter().map(|y| { *y }); //~ ERROR you seem to be using .map()
23+
//~^ HELP try
1824
x.iter().map(Clone::clone); //~ ERROR you seem to be using .map()
1925
//~^ HELP try
2026
}

0 commit comments

Comments
 (0)