Skip to content

Commit 3573695

Browse files
committed
Update clippy
1 parent 9b27303 commit 3573695

File tree

16 files changed

+182
-169
lines changed

16 files changed

+182
-169
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,7 @@ All notable changes to this project will be documented in this file.
10351035
[`redundant_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone
10361036
[`redundant_closure`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
10371037
[`redundant_closure_call`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_call
1038+
[`redundant_closure_for_method_calls`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_for_method_calls
10381039
[`redundant_field_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names
10391040
[`redundant_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern
10401041
[`redundant_pattern_matching`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_pattern_matching

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
99

10-
[There are 301 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
10+
[There are 302 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
1111

1212
We have a bunch of lint categories to allow you to choose how much Clippy is supposed to ~~annoy~~ help you:
1313

clippy_lints/src/consts.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ impl Hash for Constant {
8181
where
8282
H: Hasher,
8383
{
84+
std::mem::discriminant(self).hash(state);
8485
match *self {
8586
Constant::Str(ref s) => {
8687
s.hash(state);

clippy_lints/src/eta_reduction.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,30 @@ declare_clippy_lint! {
3232
"redundant closures, i.e., `|a| foo(a)` (which can be written as just `foo`)"
3333
}
3434

35-
declare_lint_pass!(EtaReduction => [REDUNDANT_CLOSURE]);
35+
declare_clippy_lint! {
36+
/// **What it does:** Checks for closures which only invoke a method on the closure
37+
/// argument and can be replaced by referencing the method directly.
38+
///
39+
/// **Why is this bad?** It's unnecessary to create the closure.
40+
///
41+
/// **Known problems:** rust-lang/rust-clippy#3071, rust-lang/rust-clippy#4002,
42+
/// rust-lang/rust-clippy#3942
43+
///
44+
///
45+
/// **Example:**
46+
/// ```rust,ignore
47+
/// Some('a').map(|s| s.to_uppercase());
48+
/// ```
49+
/// may be rewritten as
50+
/// ```rust,ignore
51+
/// Some('a').map(char::to_uppercase);
52+
/// ```
53+
pub REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
54+
pedantic,
55+
"redundant closures for method calls"
56+
}
57+
58+
declare_lint_pass!(EtaReduction => [REDUNDANT_CLOSURE, REDUNDANT_CLOSURE_FOR_METHOD_CALLS]);
3659

3760
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for EtaReduction {
3861
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
@@ -104,7 +127,7 @@ fn check_closure(cx: &LateContext<'_, '_>, expr: &Expr) {
104127
if let Some(name) = get_ufcs_type_name(cx, method_def_id, &args[0]);
105128

106129
then {
107-
span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure found", |db| {
130+
span_lint_and_then(cx, REDUNDANT_CLOSURE_FOR_METHOD_CALLS, expr.span, "redundant closure found", |db| {
108131
db.span_suggestion(
109132
expr.span,
110133
"remove closure as shown",

clippy_lints/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
614614
enum_glob_use::ENUM_GLOB_USE,
615615
enum_variants::MODULE_NAME_REPETITIONS,
616616
enum_variants::PUB_ENUM_VARIANT_NAMES,
617+
eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
617618
functions::TOO_MANY_LINES,
618619
if_not_else::IF_NOT_ELSE,
619620
infinite_iter::MAYBE_INFINITE_ITER,

clippy_lints/src/methods/mod.rs

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use lazy_static::lazy_static;
1010
use matches::matches;
1111
use rustc::hir;
1212
use rustc::hir::def::{DefKind, Res};
13+
use rustc::hir::intravisit::{self, Visitor};
1314
use rustc::lint::{in_external_macro, LateContext, LateLintPass, Lint, LintArray, LintContext, LintPass};
1415
use rustc::ty::{self, Predicate, Ty};
1516
use rustc::{declare_lint_pass, declare_tool_lint};
@@ -1046,7 +1047,51 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Methods {
10461047

10471048
/// Checks for the `OR_FUN_CALL` lint.
10481049
#[allow(clippy::too_many_lines)]
1049-
fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Span, name: &str, args: &[hir::Expr]) {
1050+
fn lint_or_fun_call<'a, 'tcx: 'a>(
1051+
cx: &LateContext<'a, 'tcx>,
1052+
expr: &hir::Expr,
1053+
method_span: Span,
1054+
name: &str,
1055+
args: &'tcx [hir::Expr],
1056+
) {
1057+
// Searches an expression for method calls or function calls that aren't ctors
1058+
struct FunCallFinder<'a, 'tcx: 'a> {
1059+
cx: &'a LateContext<'a, 'tcx>,
1060+
found: bool,
1061+
}
1062+
1063+
impl<'a, 'tcx> intravisit::Visitor<'tcx> for FunCallFinder<'a, 'tcx> {
1064+
fn visit_expr(&mut self, expr: &'tcx hir::Expr) {
1065+
let call_found = match &expr.node {
1066+
// ignore enum and struct constructors
1067+
hir::ExprKind::Call(..) => !is_ctor_function(self.cx, expr),
1068+
hir::ExprKind::MethodCall(..) => true,
1069+
_ => false,
1070+
};
1071+
1072+
if call_found {
1073+
// don't lint for constant values
1074+
let owner_def = self.cx.tcx.hir().get_parent_did_by_hir_id(expr.hir_id);
1075+
let promotable = self
1076+
.cx
1077+
.tcx
1078+
.rvalue_promotable_map(owner_def)
1079+
.contains(&expr.hir_id.local_id);
1080+
if !promotable {
1081+
self.found |= true;
1082+
}
1083+
}
1084+
1085+
if !self.found {
1086+
intravisit::walk_expr(self, expr);
1087+
}
1088+
}
1089+
1090+
fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> {
1091+
intravisit::NestedVisitorMap::None
1092+
}
1093+
}
1094+
10501095
/// Checks for `unwrap_or(T::new())` or `unwrap_or(T::default())`.
10511096
fn check_unwrap_or_default(
10521097
cx: &LateContext<'_, '_>,
@@ -1099,13 +1144,13 @@ fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Spa
10991144

11001145
/// Checks for `*or(foo())`.
11011146
#[allow(clippy::too_many_arguments)]
1102-
fn check_general_case(
1103-
cx: &LateContext<'_, '_>,
1147+
fn check_general_case<'a, 'tcx: 'a>(
1148+
cx: &LateContext<'a, 'tcx>,
11041149
name: &str,
11051150
method_span: Span,
11061151
fun_span: Span,
11071152
self_expr: &hir::Expr,
1108-
arg: &hir::Expr,
1153+
arg: &'tcx hir::Expr,
11091154
or_has_args: bool,
11101155
span: Span,
11111156
) {
@@ -1122,15 +1167,9 @@ fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Spa
11221167
return;
11231168
}
11241169

1125-
// ignore enum and struct constructors
1126-
if is_ctor_function(cx, &arg) {
1127-
return;
1128-
}
1129-
1130-
// don't lint for constant values
1131-
let owner_def = cx.tcx.hir().get_parent_did_by_hir_id(arg.hir_id);
1132-
let promotable = cx.tcx.rvalue_promotable_map(owner_def).contains(&arg.hir_id.local_id);
1133-
if promotable {
1170+
let mut finder = FunCallFinder { cx: &cx, found: false };
1171+
finder.visit_expr(&arg);
1172+
if !finder.found {
11341173
return;
11351174
}
11361175

0 commit comments

Comments
 (0)