{flat_,}map_identity: recognize |[x, y]| [x, y] as an identity function as well (#15229)
changelog: [`map_identity`,`flat_map_identity`]: also recognize `|[x, y]| [x, y]` fixes rust-lang/rust-clippy#15198
This commit is contained in:
commit
3c3ee9bddb
7 changed files with 75 additions and 5 deletions
|
|
@ -1896,6 +1896,7 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
|
|||
/// * `|x| { return x }`
|
||||
/// * `|x| { return x; }`
|
||||
/// * `|(x, y)| (x, y)`
|
||||
/// * `|[x, y]| [x, y]`
|
||||
///
|
||||
/// Consider calling [`is_expr_untyped_identity_function`] or [`is_expr_identity_function`] instead.
|
||||
fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
|
||||
|
|
@ -1906,9 +1907,9 @@ fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
|
|||
.get(pat.hir_id)
|
||||
.is_some_and(|mode| matches!(mode.0, ByRef::Yes(_)))
|
||||
{
|
||||
// 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.
|
||||
// If the parameter is `(x, y)` of type `&(T, T)`, or `[x, y]` of type `&[T; 2]`, then
|
||||
// due to match ergonomics, the inner patterns become references. Don't consider this
|
||||
// the identity function as that changes types.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1921,6 +1922,13 @@ fn is_body_identity_function(cx: &LateContext<'_>, func: &Body<'_>) -> bool {
|
|||
{
|
||||
pats.iter().zip(tup).all(|(pat, expr)| check_pat(cx, pat, expr))
|
||||
},
|
||||
(PatKind::Slice(before, slice, after), ExprKind::Array(arr))
|
||||
if slice.is_none() && before.len() + after.len() == arr.len() =>
|
||||
{
|
||||
(before.iter().chain(after))
|
||||
.zip(arr)
|
||||
.all(|(pat, expr)| check_pat(cx, pat, expr))
|
||||
},
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,3 +16,16 @@ fn main() {
|
|||
let _ = iterator.flatten();
|
||||
//~^ flat_map_identity
|
||||
}
|
||||
|
||||
fn issue15198() {
|
||||
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().flat_map(|[x, y]| [x, y]);
|
||||
let _ = x.iter().flat_map(|x| [x[0]]);
|
||||
|
||||
// no match ergonomics for `[i32, i32]`
|
||||
let _ = x.iter().copied().flatten();
|
||||
//~^ flat_map_identity
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,3 +16,16 @@ fn main() {
|
|||
let _ = iterator.flat_map(|x| return x);
|
||||
//~^ flat_map_identity
|
||||
}
|
||||
|
||||
fn issue15198() {
|
||||
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().flat_map(|[x, y]| [x, y]);
|
||||
let _ = x.iter().flat_map(|x| [x[0]]);
|
||||
|
||||
// no match ergonomics for `[i32, i32]`
|
||||
let _ = x.iter().copied().flat_map(|[x, y]| [x, y]);
|
||||
//~^ flat_map_identity
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,5 +19,11 @@ error: use of `flat_map` with an identity function
|
|||
LL | let _ = iterator.flat_map(|x| return x);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: use of `flat_map` with an identity function
|
||||
--> tests/ui/flat_map_identity.rs:29:31
|
||||
|
|
||||
LL | let _ = x.iter().copied().flat_map(|[x, y]| [x, y]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -87,3 +87,15 @@ fn issue13904() {
|
|||
let _ = { it }.next();
|
||||
//~^ map_identity
|
||||
}
|
||||
|
||||
// same as `issue11764`, but for arrays
|
||||
fn issue15198() {
|
||||
let x = [[1, 2], [3, 4]];
|
||||
// don't lint: `&[i32; 2]` becomes `[&i32; 2]`
|
||||
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_identity
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,3 +93,15 @@ fn issue13904() {
|
|||
let _ = { it }.map(|x| x).next();
|
||||
//~^ map_identity
|
||||
}
|
||||
|
||||
// same as `issue11764`, but for arrays
|
||||
fn issue15198() {
|
||||
let x = [[1, 2], [3, 4]];
|
||||
// don't lint: `&[i32; 2]` becomes `[&i32; 2]`
|
||||
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]);
|
||||
//~^ map_identity
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,5 +87,11 @@ error: unnecessary map of the identity function
|
|||
LL | let _ = { it }.map(|x| x).next();
|
||||
| ^^^^^^^^^^^ help: remove the call to `map`
|
||||
|
||||
error: aborting due to 13 previous errors
|
||||
error: unnecessary map of the identity function
|
||||
--> tests/ui/map_identity.rs:105:30
|
||||
|
|
||||
LL | let _ = x.iter().copied().map(|[x, y]| [x, y]);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
|
||||
|
||||
error: aborting due to 14 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue