mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-26 22:50:56 +00:00
[map_identity
]: respect match ergonomics
This commit is contained in:
parent
34b7d1559f
commit
b2cf8f7a24
4 changed files with 85 additions and 43 deletions
|
@ -2034,6 +2034,18 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||
/// Consider calling [`is_expr_untyped_identity_function`] or [`is_expr_identity_function`] instead.
|
||||
fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
|
||||
fn check_pat(cx: &LateContext<'_>, pat: &Pat<'_>, expr: &Expr<'_>) -> bool {
|
||||
if cx
|
||||
.typeck_results()
|
||||
.pat_binding_modes()
|
||||
.get(pat.hir_id)
|
||||
.is_some_and(|mode| matches!(mode, BindingMode::BindByReference(_)))
|
||||
{
|
||||
// If a tuple `(x, y)` is of type `&(i32, i32)`, then due to match ergonomics,
|
||||
// the inner patterns become references. Don't consider this the identity function
|
||||
// as that changes types.
|
||||
return false;
|
||||
}
|
||||
|
||||
match (pat.kind, expr.kind) {
|
||||
(PatKind::Binding(_, id, _, _), _) => {
|
||||
path_to_local_id(expr, id) && cx.typeck_results().expr_adjustments(expr).is_empty()
|
||||
|
|
|
@ -24,28 +24,40 @@ fn main() {
|
|||
|
||||
fn issue7189() {
|
||||
// should lint
|
||||
let x = [(1, 2), (3, 4)];
|
||||
let _ = x.iter();
|
||||
let _ = x.iter();
|
||||
let _ = x.iter();
|
||||
let x = [(1, 2), (3, 4)].iter().copied();
|
||||
let _ = x.clone();
|
||||
let _ = x.clone();
|
||||
let _ = x.clone();
|
||||
|
||||
let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))];
|
||||
let _ = y.iter();
|
||||
let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))].iter().copied();
|
||||
let _ = y.clone();
|
||||
|
||||
// should not lint
|
||||
let _ = x.iter().map(|(x, y)| (x, y, y));
|
||||
let _ = x.iter().map(|(x, _y)| (x,));
|
||||
let _ = x.iter().map(|(x, _)| (x,));
|
||||
let _ = x.iter().map(|(x, ..)| (x,));
|
||||
let _ = y.iter().map(|(x, y, (z, _))| (x, y, (z, z)));
|
||||
let _ = x.clone().map(|(x, y)| (x, y, y));
|
||||
let _ = x.clone().map(|(x, _y)| (x,));
|
||||
let _ = x.clone().map(|(x, _)| (x,));
|
||||
let _ = x.clone().map(|(x, ..)| (x,));
|
||||
let _ = y.clone().map(|(x, y, (z, _))| (x, y, (z, z)));
|
||||
let _ = y
|
||||
.iter()
|
||||
.map(|(x, y, (z, _)): &(i32, i32, (i32, (i32,)))| (x, y, (z, z)));
|
||||
.clone()
|
||||
.map(|(x, y, (z, _)): (i32, i32, (i32, (i32,)))| (x, y, (z, z)));
|
||||
let _ = y
|
||||
.iter()
|
||||
.map(|(x, y, (z, (w,))): &(i32, i32, (i32, (i32,)))| (x, y, (z, (w,))));
|
||||
.clone()
|
||||
.map(|(x, y, (z, (w,))): (i32, i32, (i32, (i32,)))| (x, y, (z, (w,))));
|
||||
}
|
||||
|
||||
fn not_identity(x: &u16) -> u16 {
|
||||
*x
|
||||
}
|
||||
|
||||
fn issue11764() {
|
||||
let x = [(1, 2), (3, 4)];
|
||||
// don't lint: this is an `Iterator<Item = &(i32, i32)>`
|
||||
// match ergonomics makes the binding patterns into references
|
||||
// so that its type changes to `Iterator<Item = (&i32, &i32)>`
|
||||
let _ = x.iter().map(|(x, y)| (x, y));
|
||||
let _ = x.iter().map(|x| (x.0,)).map(|(x,)| x);
|
||||
|
||||
// no match ergonomics for `(i32, i32)`
|
||||
let _ = x.iter().copied();
|
||||
}
|
||||
|
|
|
@ -26,30 +26,42 @@ fn main() {
|
|||
|
||||
fn issue7189() {
|
||||
// should lint
|
||||
let x = [(1, 2), (3, 4)];
|
||||
let _ = x.iter().map(|(x, y)| (x, y));
|
||||
let _ = x.iter().map(|(x, y)| {
|
||||
let x = [(1, 2), (3, 4)].iter().copied();
|
||||
let _ = x.clone().map(|(x, y)| (x, y));
|
||||
let _ = x.clone().map(|(x, y)| {
|
||||
return (x, y);
|
||||
});
|
||||
let _ = x.iter().map(|(x, y)| return (x, y));
|
||||
let _ = x.clone().map(|(x, y)| return (x, y));
|
||||
|
||||
let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))];
|
||||
let _ = y.iter().map(|(x, y, (z, (w,)))| (x, y, (z, (w,))));
|
||||
let y = [(1, 2, (3, (4,))), (5, 6, (7, (8,)))].iter().copied();
|
||||
let _ = y.clone().map(|(x, y, (z, (w,)))| (x, y, (z, (w,))));
|
||||
|
||||
// should not lint
|
||||
let _ = x.iter().map(|(x, y)| (x, y, y));
|
||||
let _ = x.iter().map(|(x, _y)| (x,));
|
||||
let _ = x.iter().map(|(x, _)| (x,));
|
||||
let _ = x.iter().map(|(x, ..)| (x,));
|
||||
let _ = y.iter().map(|(x, y, (z, _))| (x, y, (z, z)));
|
||||
let _ = x.clone().map(|(x, y)| (x, y, y));
|
||||
let _ = x.clone().map(|(x, _y)| (x,));
|
||||
let _ = x.clone().map(|(x, _)| (x,));
|
||||
let _ = x.clone().map(|(x, ..)| (x,));
|
||||
let _ = y.clone().map(|(x, y, (z, _))| (x, y, (z, z)));
|
||||
let _ = y
|
||||
.iter()
|
||||
.map(|(x, y, (z, _)): &(i32, i32, (i32, (i32,)))| (x, y, (z, z)));
|
||||
.clone()
|
||||
.map(|(x, y, (z, _)): (i32, i32, (i32, (i32,)))| (x, y, (z, z)));
|
||||
let _ = y
|
||||
.iter()
|
||||
.map(|(x, y, (z, (w,))): &(i32, i32, (i32, (i32,)))| (x, y, (z, (w,))));
|
||||
.clone()
|
||||
.map(|(x, y, (z, (w,))): (i32, i32, (i32, (i32,)))| (x, y, (z, (w,))));
|
||||
}
|
||||
|
||||
fn not_identity(x: &u16) -> u16 {
|
||||
*x
|
||||
}
|
||||
|
||||
fn issue11764() {
|
||||
let x = [(1, 2), (3, 4)];
|
||||
// don't lint: this is an `Iterator<Item = &(i32, i32)>`
|
||||
// match ergonomics makes the binding patterns into references
|
||||
// so that its type changes to `Iterator<Item = (&i32, &i32)>`
|
||||
let _ = x.iter().map(|(x, y)| (x, y));
|
||||
let _ = x.iter().map(|x| (x.0,)).map(|(x,)| x);
|
||||
|
||||
// no match ergonomics for `(i32, i32)`
|
||||
let _ = x.iter().copied().map(|(x, y)| (x, y));
|
||||
}
|
||||
|
|
|
@ -41,31 +41,37 @@ LL | let _: Result<u32, u32> = Ok(1).map_err(|a| a);
|
|||
| ^^^^^^^^^^^^^^^ help: remove the call to `map_err`
|
||||
|
||||
error: unnecessary map of the identity function
|
||||
--> $DIR/map_identity.rs:30:21
|
||||
--> $DIR/map_identity.rs:30:22
|
||||
|
|
||||
LL | let _ = x.iter().map(|(x, y)| (x, y));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
|
||||
LL | let _ = x.clone().map(|(x, y)| (x, y));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
|
||||
|
||||
error: unnecessary map of the identity function
|
||||
--> $DIR/map_identity.rs:31:21
|
||||
--> $DIR/map_identity.rs:31:22
|
||||
|
|
||||
LL | let _ = x.iter().map(|(x, y)| {
|
||||
| _____________________^
|
||||
LL | let _ = x.clone().map(|(x, y)| {
|
||||
| ______________________^
|
||||
LL | | return (x, y);
|
||||
LL | | });
|
||||
| |______^ help: remove the call to `map`
|
||||
|
||||
error: unnecessary map of the identity function
|
||||
--> $DIR/map_identity.rs:34:21
|
||||
--> $DIR/map_identity.rs:34:22
|
||||
|
|
||||
LL | let _ = x.iter().map(|(x, y)| return (x, y));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
|
||||
LL | let _ = x.clone().map(|(x, y)| return (x, y));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
|
||||
|
||||
error: unnecessary map of the identity function
|
||||
--> $DIR/map_identity.rs:37:21
|
||||
--> $DIR/map_identity.rs:37:22
|
||||
|
|
||||
LL | let _ = y.iter().map(|(x, y, (z, (w,)))| (x, y, (z, (w,))));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
|
||||
LL | let _ = y.clone().map(|(x, y, (z, (w,)))| (x, y, (z, (w,))));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
error: unnecessary map of the identity function
|
||||
--> $DIR/map_identity.rs:66:30
|
||||
|
|
||||
LL | let _ = x.iter().copied().map(|(x, y)| (x, y));
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
|
|
Loading…
Reference in a new issue