Skip to content

Commit 2d7954c

Browse files
committed
fix(useless_conversion): stop adjustments when target type is reached
1 parent 80fce9b commit 2d7954c

File tree

4 files changed

+101
-52
lines changed

4 files changed

+101
-52
lines changed

clippy_lints/src/useless_conversion.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,13 +456,25 @@ fn has_eligible_receiver(cx: &LateContext<'_>, recv: &Expr<'_>, expr: &Expr<'_>)
456456

457457
fn adjustments(cx: &LateContext<'_>, expr: &Expr<'_>) -> String {
458458
let mut prefix = String::new();
459-
for adj in cx.typeck_results().expr_adjustments(expr) {
459+
460+
let adjustments = cx.typeck_results().expr_adjustments(expr);
461+
462+
let [.., last] = adjustments else { return prefix };
463+
let target = last.target;
464+
465+
for adj in adjustments {
460466
match adj.kind {
461467
Adjust::Deref(_) => prefix = format!("*{prefix}"),
462468
Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. })) => prefix = format!("&mut {prefix}"),
463469
Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)) => prefix = format!("&{prefix}"),
464470
_ => {},
465471
}
472+
473+
// Stop once we reach the final target type.
474+
// This prevents over-adjusting (e.g. suggesting &**y instead of *y).
475+
if adj.target == target {
476+
break;
477+
}
466478
}
467479
prefix
468480
}

tests/ui/useless_conversion.fixed

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ fn main() {
131131
dont_lint_into_iter_on_copy_iter();
132132
dont_lint_into_iter_on_static_copy_iter();
133133

134+
#[allow(clippy::into_iter_on_ref)]
135+
{
136+
// triggers the IntoIterator trait
137+
fn consume(_: impl IntoIterator) {}
138+
139+
// Should suggest `*items` instead of `&**items`
140+
let items = &&[1, 2, 3];
141+
consume(items.into_iter());
142+
}
143+
134144
let _: String = "foo".into();
135145
let _: String = From::from("foo");
136146
let _ = String::from("foo");

tests/ui/useless_conversion.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,16 @@ fn main() {
131131
dont_lint_into_iter_on_copy_iter();
132132
dont_lint_into_iter_on_static_copy_iter();
133133

134+
#[allow(clippy::into_iter_on_ref)]
135+
{
136+
// triggers the IntoIterator trait
137+
fn consume(_: impl IntoIterator) {}
138+
139+
// Should suggest `*items` instead of `&**items`
140+
let items = &&[1, 2, 3];
141+
consume(items.into_iter());
142+
}
143+
134144
let _: String = "foo".into();
135145
let _: String = From::from("foo");
136146
let _ = String::from("foo");

0 commit comments

Comments
 (0)