Skip to content

Commit f1a2586

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

7 files changed

+127
-51
lines changed

clippy_lints/src/useless_conversion.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,13 +456,26 @@ 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+
463+
let [.., last] = adjustments else { return prefix };
464+
let target = last.target;
465+
466+
for adj in adjustments {
460467
match adj.kind {
461468
Adjust::Deref(_) => prefix = format!("*{prefix}"),
462469
Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. })) => prefix = format!("&mut {prefix}"),
463470
Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)) => prefix = format!("&{prefix}"),
464471
_ => {},
465472
}
473+
474+
// Stop once we reach the final target type.
475+
// This prevents over-adjusting (e.g. suggesting &**y instead of *y).
476+
if adj.target == target {
477+
break;
478+
}
466479
}
467480
prefix
468481
}

tests/ui/useless_conversion.fixed

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,13 @@ 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+
// Should suggest `*items` instead of `&**items`
137+
let items = &&[1, 2, 3];
138+
let _ = items.into_iter();
139+
}
140+
134141
let _: String = "foo".into();
135142
let _: String = From::from("foo");
136143
let _ = String::from("foo");

tests/ui/useless_conversion.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,13 @@ 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+
// Should suggest `*items` instead of `&**items`
137+
let items = &&[1, 2, 3];
138+
let _ = items.into_iter();
139+
}
140+
134141
let _: String = "foo".into();
135142
let _: String = From::from("foo");
136143
let _ = String::from("foo");

0 commit comments

Comments
 (0)