Skip to content

Commit b0d7aea

Browse files
committed
Fixes 3289, cmp_owned wording and false positive
1 parent f6882ed commit b0d7aea

File tree

3 files changed

+47
-8
lines changed

3 files changed

+47
-8
lines changed

clippy_lints/src/misc.rs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -535,10 +535,29 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr, other: &Expr) {
535535
return;
536536
}
537537

538+
let other_gets_derefed = match other.node {
539+
ExprKind::Unary(UnDeref, _) => true,
540+
_ => false,
541+
};
542+
543+
let (lint_span, try_hint) = if deref_arg_impl_partial_eq_other {
544+
// suggest deref on the left
545+
(expr.span, format!("*{}", snip))
546+
} else if other_gets_derefed {
547+
// suggest dropping the to_owned on the left and the deref on the right
548+
let other_snippet = snippet(cx, other.span, "..").into_owned();
549+
let other_without_deref = other_snippet.trim_left_matches("*");
550+
551+
(expr.span.to(other.span), format!("{} == {}", snip.to_string(), other_without_deref))
552+
} else {
553+
// suggest dropping the to_owned on the left
554+
(expr.span, snip.to_string())
555+
};
556+
538557
span_lint_and_then(
539558
cx,
540559
CMP_OWNED,
541-
expr.span,
560+
lint_span,
542561
"this creates an owned instance just for comparison",
543562
|db| {
544563
// this is as good as our recursion check can get, we can't prove that the
@@ -554,15 +573,14 @@ fn check_to_owned(cx: &LateContext<'_, '_>, expr: &Expr, other: &Expr) {
554573
// we are implementing PartialEq, don't suggest not doing `to_owned`, otherwise
555574
// we go into
556575
// recursion
557-
db.span_label(expr.span, "try calling implementing the comparison without allocating");
576+
db.span_label(lint_span, "try implementing the comparison without allocating");
558577
return;
559578
}
560579
}
561580
}
562581
}
563-
let try_hint = if deref_arg_impl_partial_eq_other { format!("*{}", snip) } else { snip.to_string() };
564582
db.span_suggestion_with_applicability(
565-
expr.span,
583+
lint_span,
566584
"try",
567585
try_hint,
568586
Applicability::MachineApplicable, // snippet

tests/ui/cmp_owned.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ fn main() {
3535
"abc".chars().filter(|c| c.to_owned() != 'X');
3636

3737
"abc".chars().filter(|c| *c != 'X');
38+
39+
let x = &Baz;
40+
let y = &Baz;
41+
42+
y.to_owned() == *x;
3843
}
3944

4045
struct Foo;
@@ -67,3 +72,13 @@ impl std::borrow::Borrow<Foo> for Bar {
6772
&FOO
6873
}
6974
}
75+
76+
#[derive(PartialEq)]
77+
struct Baz;
78+
79+
impl ToOwned for Baz {
80+
type Owned = Baz;
81+
fn to_owned(&self) -> Baz {
82+
Baz
83+
}
84+
}

tests/ui/cmp_owned.stderr

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,16 @@ error: this creates an owned instance just for comparison
3737
| ^^^^^^^^^^^^ help: try: `*c`
3838

3939
error: this creates an owned instance just for comparison
40-
--> $DIR/cmp_owned.rs:44:9
40+
--> $DIR/cmp_owned.rs:42:5
4141
|
42-
44 | self.to_owned() == *other
43-
| ^^^^^^^^^^^^^^^ try calling implementing the comparison without allocating
42+
42 | y.to_owned() == *x;
43+
| ^^^^^^^^^^^^^^^^^^ help: try: `y == x`
4444

45-
error: aborting due to 7 previous errors
45+
error: this creates an owned instance just for comparison
46+
--> $DIR/cmp_owned.rs:49:9
47+
|
48+
49 | self.to_owned() == *other
49+
| ^^^^^^^^^^^^^^^^^^^^^^^^^ try implementing the comparison without allocating
50+
51+
error: aborting due to 8 previous errors
4652

0 commit comments

Comments
 (0)