useless_conversion: also fire inside compiler desugarings (#16594)

Using `e.span.from_expansion()` alone prevented the lint from firing
within compiler-desugared expressions, e.g. `async fn`, `for` loops, or
`?`.

changelog: [`useless_conversion`]: also fire inside compiler desugarings

close rust-lang/rust-clippy#16590
This commit is contained in:
llogiq
2026-02-22 13:02:19 +00:00
committed by GitHub
4 changed files with 109 additions and 3 deletions
+4 -2
View File
@@ -157,7 +157,9 @@ fn into_iter_deep_call<'hir>(cx: &LateContext<'_>, mut expr: &'hir Expr<'hir>) -
impl<'tcx> LateLintPass<'tcx> for UselessConversion {
fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
if e.span.from_expansion() {
self.expn_depth += 1;
if e.span.desugaring_kind().is_none() {
self.expn_depth += 1;
}
return;
}
@@ -437,7 +439,7 @@ fn check_expr_post(&mut self, _: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
if Some(&e.hir_id) == self.try_desugar_arm.last() {
self.try_desugar_arm.pop();
}
if e.span.from_expansion() {
if e.span.from_expansion() && e.span.desugaring_kind().is_none() {
self.expn_depth -= 1;
}
}
+31
View File
@@ -463,3 +463,34 @@ fn issue16165() {
for _ in mac!(iter [1, 2]) {}
//~^ useless_conversion
}
fn takes_into_iter_usize(_: impl IntoIterator<Item = usize>) {}
fn takes_into_iter_usize_result(_: impl IntoIterator<Item = usize>) -> Result<(), ()> {
Ok(())
}
async fn issue16590() {
let a: Vec<usize> = vec![];
let b: Vec<usize> = vec![];
takes_into_iter_usize(b);
//~^ useless_conversion
}
fn in_for_loop() {
let a: Vec<usize> = vec![1, 2, 3];
let b: Vec<usize> = vec![4, 5, 6];
for _ in &a {
takes_into_iter_usize(b.clone());
//~^ useless_conversion
}
}
fn after_question_mark() -> Result<(), ()> {
let b: Vec<usize> = vec![4, 5, 6];
takes_into_iter_usize_result(b.clone())?;
//~^ useless_conversion
Ok(())
}
+31
View File
@@ -463,3 +463,34 @@ macro_rules! mac {
for _ in mac!(iter [1, 2]).into_iter() {}
//~^ useless_conversion
}
fn takes_into_iter_usize(_: impl IntoIterator<Item = usize>) {}
fn takes_into_iter_usize_result(_: impl IntoIterator<Item = usize>) -> Result<(), ()> {
Ok(())
}
async fn issue16590() {
let a: Vec<usize> = vec![];
let b: Vec<usize> = vec![];
takes_into_iter_usize(b.into_iter());
//~^ useless_conversion
}
fn in_for_loop() {
let a: Vec<usize> = vec![1, 2, 3];
let b: Vec<usize> = vec![4, 5, 6];
for _ in &a {
takes_into_iter_usize(b.clone().into_iter());
//~^ useless_conversion
}
}
fn after_question_mark() -> Result<(), ()> {
let b: Vec<usize> = vec![4, 5, 6];
takes_into_iter_usize_result(b.clone().into_iter())?;
//~^ useless_conversion
Ok(())
}
+43 -1
View File
@@ -412,5 +412,47 @@ error: useless conversion to the same type: `std::slice::Iter<'_, i32>`
LL | for _ in mac!(iter [1, 2]).into_iter() {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `mac!(iter [1, 2])`
error: aborting due to 45 previous errors
error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
--> tests/ui/useless_conversion.rs:476:27
|
LL | takes_into_iter_usize(b.into_iter());
| ^------------
| |
| help: consider removing the `.into_iter()`
|
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
--> tests/ui/useless_conversion.rs:467:34
|
LL | fn takes_into_iter_usize(_: impl IntoIterator<Item = usize>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
--> tests/ui/useless_conversion.rs:485:31
|
LL | takes_into_iter_usize(b.clone().into_iter());
| ^^^^^^^^^------------
| |
| help: consider removing the `.into_iter()`
|
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
--> tests/ui/useless_conversion.rs:467:34
|
LL | fn takes_into_iter_usize(_: impl IntoIterator<Item = usize>) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
--> tests/ui/useless_conversion.rs:493:34
|
LL | takes_into_iter_usize_result(b.clone().into_iter())?;
| ^^^^^^^^^------------
| |
| help: consider removing the `.into_iter()`
|
note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
--> tests/ui/useless_conversion.rs:468:41
|
LL | fn takes_into_iter_usize_result(_: impl IntoIterator<Item = usize>) -> Result<(), ()> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 48 previous errors