We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
map_identity
1 parent 090df7a commit 875de5bCopy full SHA for 875de5b
clippy_utils/src/lib.rs
@@ -2032,17 +2032,26 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
2032
/// * `|x| return x`
2033
/// * `|x| { return x }`
2034
/// * `|x| { return x; }`
2035
+/// * `|(x, y)| (x, y)`
2036
///
2037
/// Consider calling [`is_expr_untyped_identity_function`] or [`is_expr_identity_function`] instead.
2038
fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
- let id = if_chain! {
2039
- if let [param] = func.params;
2040
- if let PatKind::Binding(_, id, _, _) = param.pat.kind;
2041
- then {
2042
- id
2043
- } else {
2044
- return false;
+ fn check_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
+ match (pat.kind, expr.kind) {
+ (PatKind::Binding(_, id, _, _), _) => {
+ path_to_local_id(expr, id) && cx.typeck_results().expr_adjustments(expr).is_empty()
+ },
+ (PatKind::Tuple(pats, dotdot), ExprKind::Tup(tup))
2045
+ if dotdot.as_opt_usize().is_none() && pats.len() == tup.len() =>
2046
+ {
2047
+ pats.iter().zip(tup).all(|(pat, expr)| check_pat(cx, pat, expr))
2048
2049
+ _ => false,
2050
}
2051
+ }
2052
+
2053
+ let [param] = func.params else {
2054
+ return false;
2055
};
2056
2057
let mut expr = func.value;
@@ -2063,7 +2072,9 @@ fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
2063
2072
2064
2073
2065
2074
},
2066
- _ => return path_to_local_id(expr, id) && cx.typeck_results().expr_adjustments(expr).is_empty(),
2075
+ _ => {
2076
+ return check_pat(cx, param.pat, expr);
2077
2067
2078
2068
2079
2069
2080
lintcheck/src/main.rs
@@ -523,7 +523,7 @@ fn gather_stats(clippy_warnings: &[ClippyWarning]) -> (String, HashMap<&String,
523
.for_each(|wrn| *counter.entry(&wrn.lint_type).or_insert(0) += 1);
524
525
// collect into a tupled list for sorting
526
- let mut stats: Vec<(&&String, &usize)> = counter.iter().map(|(lint, count)| (lint, count)).collect();
+ let mut stats: Vec<(&&String, &usize)> = counter.iter().collect();
527
// sort by "000{count} {clippy::lintname}"
528
// to not have a lint with 200 and 2 warnings take the same spot
529
stats.sort_by_key(|(lint, count)| format!("{count:0>4}, {lint}"));
tests/ui/map_identity.fixed
@@ -22,6 +22,30 @@ fn main() {
22
let _ = Ok(1).map_err(std::convert::identity::<u32>);
23
24
25
+fn issue7189() {
26
+ // should lint
27
+ let x = [(1, 2), (3, 4)];
28
+ let _ = x.iter();
29
30
31
32
+ let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))];
33
+ let _ = y.iter();
34
+ let _ = y
35
+ .iter()
36
+ .map(|(x, y, (z, (w,))): &(i32, i32, (i32, (i32,)))| (x, y, (z, (w,))));
37
38
+ // should not lint
39
+ let _ = x.iter().map(|(x, y)| (x, y, y));
40
+ let _ = x.iter().map(|(x, _y)| (x,));
41
+ let _ = x.iter().map(|(x, _)| (x,));
42
+ let _ = x.iter().map(|(x, ..)| (x,));
43
+ let _ = y.iter().map(|(x, y, (z, _))| (x, y, (z, z)));
44
45
46
+ .map(|(x, y, (z, _)): &(i32, i32, (i32, (i32,)))| (x, y, (z, z)));
47
+}
48
49
fn not_identity(x: &u16) -> u16 {
50
*x
51
tests/ui/map_identity.rs
@@ -24,6 +24,32 @@ fn main() {
+ let _ = x.iter().map(|(x, y)| (x, y));
+ let _ = x.iter().map(|(x, y)| {
+ return (x, y);
+ });
+ let _ = x.iter().map(|(x, y)| return (x, y));
+ let _ = y.iter().map(|(x, y, (z, (w,)))| (x, y, (z, (w,))));
52
53
54
55
tests/ui/map_identity.stderr
@@ -40,5 +40,32 @@ error: unnecessary map of the identity function
LL | let _: Result<u32, u32> = Ok(1).map_err(|a| a);
| ^^^^^^^^^^^^^^^ help: remove the call to `map_err`
-error: aborting due to 6 previous errors
+error: unnecessary map of the identity function
+ --> $DIR/map_identity.rs:30:21
+ |
+LL | let _ = x.iter().map(|(x, y)| (x, y));
+ | ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
+ --> $DIR/map_identity.rs:31:21
+LL | let _ = x.iter().map(|(x, y)| {
+ | _____________________^
+LL | | return (x, y);
+LL | | });
56
+ | |______^ help: remove the call to `map`
57
58
59
+ --> $DIR/map_identity.rs:34:21
60
61
+LL | let _ = x.iter().map(|(x, y)| return (x, y));
62
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
63
64
65
+ --> $DIR/map_identity.rs:37:21
66
67
+LL | let _ = y.iter().map(|(x, y, (z, (w,)))| (x, y, (z, (w,))));
68
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
69
70
+error: aborting due to 10 previous errors
71
0 commit comments