Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
move closures to seperate fns, remove known problems
  • Loading branch information
DevinR528 committed Apr 20, 2020
commit 51c2325dd7cdfb8c12ec55421270903df7f26d3e
92 changes: 49 additions & 43 deletions clippy_lints/src/if_let_mutex.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::utils::{match_type, paths, span_lint_and_help};
use if_chain::if_chain;
use rustc_hir::{Expr, ExprKind, MatchSource, StmtKind};
use rustc_hir::{Arm, Expr, ExprKind, MatchSource, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};

Expand All @@ -11,7 +11,7 @@ declare_clippy_lint! {
/// **Why is this bad?** The Mutex lock remains held for the whole
/// `if let ... else` block and deadlocks.
///
/// **Known problems:** This lint does not generate an auto-applicable suggestion.
/// **Known problems:** None.
///
/// **Example:**
///
Expand Down Expand Up @@ -49,47 +49,7 @@ impl LateLintPass<'_, '_> for IfLetMutex {
if match_type(cx, ty, &paths::MUTEX); // make sure receiver is Mutex
if method_chain_names(op, 10).iter().any(|s| s == "lock"); // and lock is called

if arms.iter().any(|arm| if_chain! {
if let ExprKind::Block(ref block, _l) = arm.body.kind;
if block.stmts.iter().any(|stmt| match stmt.kind {
StmtKind::Local(l) => if_chain! {
if let Some(ex) = l.init;
if let ExprKind::MethodCall(_, _, _) = op.kind;
if method_chain_names(ex, 10).iter().any(|s| s == "lock"); // and lock is called
then {
match_type_method_chain(cx, ex, 5)
} else {
false
}
},
StmtKind::Expr(e) => if_chain! {
if let ExprKind::MethodCall(_, _, _) = e.kind;
if method_chain_names(e, 10).iter().any(|s| s == "lock"); // and lock is called
then {
match_type_method_chain(cx, ex, 5)
} else {
false
}
},
StmtKind::Semi(e) => if_chain! {
if let ExprKind::MethodCall(_, _, _) = e.kind;
if method_chain_names(e, 10).iter().any(|s| s == "lock"); // and lock is called
then {
match_type_method_chain(cx, ex, 5)
} else {
false
}
},
_ => {
false
},
});
then {
true
} else {
false
}
});
if arms.iter().any(|arm| matching_arm(arm, op, ex, cx));
then {
span_lint_and_help(
cx,
Expand All @@ -103,6 +63,52 @@ impl LateLintPass<'_, '_> for IfLetMutex {
}
}

fn matching_arm(arm: &Arm<'_>, op: &Expr<'_>, ex: &Expr<'_>, cx: &LateContext<'_, '_>) -> bool {
if_chain! {
if let ExprKind::Block(ref block, _l) = arm.body.kind;
if block.stmts.iter().any(|stmt| matching_stmt(stmt, op, ex, cx));
then {
true
} else {
false
}
}
}

fn matching_stmt(stmt: &Stmt<'_>, op: &Expr<'_>, ex: &Expr<'_>, cx: &LateContext<'_, '_>) -> bool {
match stmt.kind {
StmtKind::Local(l) => if_chain! {
if let Some(ex) = l.init;
if let ExprKind::MethodCall(_, _, _) = op.kind;
if method_chain_names(ex, 10).iter().any(|s| s == "lock"); // and lock is called
then {
match_type_method_chain(cx, ex, 5)
} else {
false
}
},
StmtKind::Expr(e) => if_chain! {
if let ExprKind::MethodCall(_, _, _) = e.kind;
if method_chain_names(e, 10).iter().any(|s| s == "lock"); // and lock is called
then {
match_type_method_chain(cx, ex, 5)
} else {
false
}
},
StmtKind::Semi(e) => if_chain! {
if let ExprKind::MethodCall(_, _, _) = e.kind;
if method_chain_names(e, 10).iter().any(|s| s == "lock"); // and lock is called
then {
match_type_method_chain(cx, ex, 5)
} else {
false
}
},
_ => false,
}
}

/// Return the names of `max_depth` number of methods called in the chain.
fn method_chain_names<'tcx>(expr: &'tcx Expr<'tcx>, max_depth: usize) -> Vec<String> {
let mut method_names = Vec::with_capacity(max_depth);
Expand Down
7 changes: 0 additions & 7 deletions tests/ui/redundant_pattern_matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,3 @@ fn returns_unit() {
false
};
}

fn issue_5271() {
let hello = Some(String::from("hello"));
let _x = match hello {
s @ _ => drop(s),
};
}