Skip to content

Commit 1607099

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

File tree

4 files changed

+77
-51
lines changed

4 files changed

+77
-51
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: 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)