Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2df6406

Browse files
committedDec 26, 2023
Auto merge of #118431 - sjwang05:issue-44695, r=estebank
Emit better suggestions for `&T == T` and `T == &T` Fixes #40660 Fixes #44695
2 parents deace71 + 2618e0f commit 2df6406

File tree

13 files changed

+668
-174
lines changed

13 files changed

+668
-174
lines changed
 

‎Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4563,6 +4563,7 @@ checksum = "8ba09476327c4b70ccefb6180f046ef588c26a24cf5d269a9feba316eb4f029f"
45634563
name = "rustc_trait_selection"
45644564
version = "0.0.0"
45654565
dependencies = [
4566+
"itertools",
45664567
"rustc_ast",
45674568
"rustc_attr",
45684569
"rustc_data_structures",

‎compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2443,7 +2443,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24432443
}
24442444
};
24452445

2446-
// Suggest dereferencing the lhs for expressions such as `&T == T`
2446+
// Suggest dereferencing the lhs for expressions such as `&T <= T`
24472447
if let Some(hir::Node::Expr(hir::Expr {
24482448
kind: hir::ExprKind::Binary(_, lhs, ..),
24492449
..

‎compiler/rustc_hir_typeck/src/op.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
4747
if let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty) {
4848
if self
4949
.lookup_op_method(
50-
lhs_deref_ty,
50+
(lhs, lhs_deref_ty),
5151
Some((rhs, rhs_ty)),
5252
Op::Binary(op, IsAssign::Yes),
5353
expected,
@@ -58,7 +58,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
5858
// emitted a better suggestion during error handling in check_overloaded_binop.
5959
if self
6060
.lookup_op_method(
61-
lhs_ty,
61+
(lhs, lhs_ty),
6262
Some((rhs, rhs_ty)),
6363
Op::Binary(op, IsAssign::Yes),
6464
expected,
@@ -246,7 +246,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
246246
});
247247

248248
let result = self.lookup_op_method(
249-
lhs_ty,
249+
(lhs_expr, lhs_ty),
250250
Some((rhs_expr, rhs_ty_var)),
251251
Op::Binary(op, is_assign),
252252
expected,
@@ -391,7 +391,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
391391
|err: &mut DiagnosticBuilder<'_, _>, lhs_deref_ty: Ty<'tcx>| {
392392
if self
393393
.lookup_op_method(
394-
lhs_deref_ty,
394+
(lhs_expr, lhs_deref_ty),
395395
Some((rhs_expr, rhs_ty)),
396396
Op::Binary(op, is_assign),
397397
expected,
@@ -424,7 +424,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
424424
rhs_new_mutbl: Option<ast::Mutability>| {
425425
if self
426426
.lookup_op_method(
427-
lhs_adjusted_ty,
427+
(lhs_expr, lhs_adjusted_ty),
428428
Some((rhs_expr, rhs_adjusted_ty)),
429429
Op::Binary(op, is_assign),
430430
expected,
@@ -479,7 +479,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
479479

480480
let is_compatible_after_call = |lhs_ty, rhs_ty| {
481481
self.lookup_op_method(
482-
lhs_ty,
482+
(lhs_expr, lhs_ty),
483483
Some((rhs_expr, rhs_ty)),
484484
Op::Binary(op, is_assign),
485485
expected,
@@ -578,7 +578,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
578578
// suggestion for the user.
579579
let errors = self
580580
.lookup_op_method(
581-
lhs_ty,
581+
(lhs_expr, lhs_ty),
582582
Some((rhs_expr, rhs_ty)),
583583
Op::Binary(op, is_assign),
584584
expected,
@@ -779,7 +779,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
779779
expected: Expectation<'tcx>,
780780
) -> Ty<'tcx> {
781781
assert!(op.is_by_value());
782-
match self.lookup_op_method(operand_ty, None, Op::Unary(op, ex.span), expected) {
782+
match self.lookup_op_method((ex, operand_ty), None, Op::Unary(op, ex.span), expected) {
783783
Ok(method) => {
784784
self.write_method_call_and_enforce_effects(ex.hir_id, ex.span, method);
785785
method.sig.output()
@@ -865,7 +865,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
865865

866866
fn lookup_op_method(
867867
&self,
868-
lhs_ty: Ty<'tcx>,
868+
(lhs_expr, lhs_ty): (&'tcx hir::Expr<'tcx>, Ty<'tcx>),
869869
opt_rhs: Option<(&'tcx hir::Expr<'tcx>, Ty<'tcx>)>,
870870
op: Op,
871871
expected: Expectation<'tcx>,
@@ -909,8 +909,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
909909
let cause = self.cause(
910910
span,
911911
traits::BinOp {
912+
lhs_hir_id: lhs_expr.hir_id,
913+
rhs_hir_id: opt_rhs_expr.map(|expr| expr.hir_id),
912914
rhs_span: opt_rhs_expr.map(|expr| expr.span),
913-
is_lit: opt_rhs_expr.is_some_and(|expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
915+
rhs_is_lit: opt_rhs_expr
916+
.is_some_and(|expr| matches!(expr.kind, hir::ExprKind::Lit(_))),
914917
output_ty: expected.only_has_type(self),
915918
},
916919
);

‎compiler/rustc_middle/src/traits/mod.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,8 +429,10 @@ pub enum ObligationCauseCode<'tcx> {
429429
MatchImpl(ObligationCause<'tcx>, DefId),
430430

431431
BinOp {
432+
lhs_hir_id: hir::HirId,
433+
rhs_hir_id: Option<hir::HirId>,
432434
rhs_span: Option<Span>,
433-
is_lit: bool,
435+
rhs_is_lit: bool,
434436
output_ty: Option<Ty<'tcx>>,
435437
},
436438

@@ -510,6 +512,21 @@ impl<'tcx> ObligationCauseCode<'tcx> {
510512
base_cause
511513
}
512514

515+
/// Returns the base obligation and the base trait predicate, if any, ignoring
516+
/// derived obligations.
517+
pub fn peel_derives_with_predicate(&self) -> (&Self, Option<ty::PolyTraitPredicate<'tcx>>) {
518+
let mut base_cause = self;
519+
let mut base_trait_pred = None;
520+
while let Some((parent_code, parent_pred)) = base_cause.parent() {
521+
base_cause = parent_code;
522+
if let Some(parent_pred) = parent_pred {
523+
base_trait_pred = Some(parent_pred);
524+
}
525+
}
526+
527+
(base_cause, base_trait_pred)
528+
}
529+
513530
pub fn parent(&self) -> Option<(&Self, Option<ty::PolyTraitPredicate<'tcx>>)> {
514531
match self {
515532
FunctionArgumentObligation { parent_code, .. } => Some((parent_code, None)),

‎compiler/rustc_trait_selection/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ edition = "2021"
55

66
[dependencies]
77
# tidy-alphabetical-start
8+
itertools = "0.11.0"
89
rustc_ast = { path = "../rustc_ast" }
910
rustc_attr = { path = "../rustc_attr" }
1011
rustc_data_structures = { path = "../rustc_data_structures" }

‎compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

Lines changed: 257 additions & 108 deletions
Large diffs are not rendered by default.

‎tests/ui/binop/binary-op-suggest-deref.fixed

Lines changed: 0 additions & 8 deletions
This file was deleted.
Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,75 @@
1-
// Issue #52544
2-
// run-rustfix
1+
#![allow(dead_code)]
32

4-
fn main() {
3+
fn foo() {
4+
// Issue #52544
55
let i: &i64 = &1;
66
if i < 0 {}
77
//~^ ERROR mismatched types [E0308]
88
}
9+
10+
fn bar() {
11+
// Issue #40660
12+
let foo = &&0;
13+
14+
// Dereference LHS
15+
_ = foo == 0;
16+
//~^ERROR can't compare `&&{integer}` with `{integer}` [E0277]
17+
_ = foo == &0;
18+
//~^ERROR can't compare `&{integer}` with `{integer}` [E0277]
19+
_ = &&&&foo == 0;
20+
//~^ERROR can't compare `&&&&&&{integer}` with `{integer}` [E0277]
21+
_ = *foo == 0;
22+
//~^ERROR can't compare `&{integer}` with `{integer}` [E0277]
23+
_ = &&foo == &&0;
24+
//~^ERROR can't compare `&&{integer}` with `{integer}` [E0277]
25+
_ = &Box::new(42) == 42;
26+
//~^ERROR can't compare `&Box<{integer}>` with `{integer}` [E0277]
27+
_ = &Box::new(&Box::new(&42)) == 42;
28+
//~^ERROR can't compare `&Box<&Box<&{integer}>>` with `{integer}` [E0277]
29+
30+
// Dereference RHS
31+
_ = 0 == foo;
32+
//~^ERROR can't compare `{integer}` with `&&{integer}` [E0277]
33+
_ = &0 == foo;
34+
//~^ERROR can't compare `{integer}` with `&{integer}` [E0277]
35+
_ = 0 == &&&&foo;
36+
//~^ERROR can't compare `{integer}` with `&&&&&&{integer}` [E0277]
37+
_ = 0 == *foo;
38+
//~^ERROR can't compare `{integer}` with `&{integer}` [E0277]
39+
_ = &&0 == &&foo;
40+
//~^ERROR can't compare `{integer}` with `&&{integer}` [E0277]
41+
42+
// Dereference both sides
43+
_ = &Box::new(Box::new(42)) == &foo;
44+
//~^ERROR can't compare `Box<Box<{integer}>>` with `&&{integer}` [E0277]
45+
_ = &Box::new(42) == &foo;
46+
//~^ERROR can't compare `Box<{integer}>` with `&&{integer}` [E0277]
47+
_ = &Box::new(Box::new(Box::new(Box::new(42)))) == &foo;
48+
//~^ERROR can't compare `Box<Box<Box<Box<{integer}>>>>` with `&&{integer}` [E0277]
49+
_ = &foo == &Box::new(Box::new(Box::new(Box::new(42))));
50+
//~^ERROR can't compare `&&{integer}` with `Box<Box<Box<Box<{integer}>>>>` [E0277]
51+
52+
// Don't suggest dereferencing the LHS; suggest boxing the RHS instead
53+
_ = Box::new(42) == 42;
54+
//~^ERROR mismatched types [E0308]
55+
56+
// Don't suggest dereferencing with types that can't be compared
57+
struct Foo;
58+
_ = &&0 == Foo;
59+
//~^ERROR can't compare `&&{integer}` with `Foo` [E0277]
60+
_ = Foo == &&0;
61+
//~^ERROR binary operation `==` cannot be applied to type `Foo` [E0369]
62+
}
63+
64+
fn baz() {
65+
// Issue #44695
66+
let owned = "foo".to_owned();
67+
let string_ref = &owned;
68+
let partial = "foobar";
69+
_ = string_ref == partial[..3];
70+
//~^ERROR can't compare `&String` with `str` [E0277]
71+
_ = partial[..3] == string_ref;
72+
//~^ERROR can't compare `str` with `&String` [E0277]
73+
}
74+
75+
fn main() {}

‎tests/ui/binop/binary-op-suggest-deref.stderr

Lines changed: 294 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,298 @@ help: consider dereferencing the borrow
99
LL | if *i < 0 {}
1010
| +
1111

12-
error: aborting due to 1 previous error
12+
error[E0277]: can't compare `&&{integer}` with `{integer}`
13+
--> $DIR/binary-op-suggest-deref.rs:15:13
14+
|
15+
LL | _ = foo == 0;
16+
| ^^ no implementation for `&&{integer} == {integer}`
17+
|
18+
= help: the trait `PartialEq<{integer}>` is not implemented for `&&{integer}`
19+
help: consider dereferencing here
20+
|
21+
LL | _ = **foo == 0;
22+
| ++
23+
24+
error[E0277]: can't compare `&{integer}` with `{integer}`
25+
--> $DIR/binary-op-suggest-deref.rs:17:13
26+
|
27+
LL | _ = foo == &0;
28+
| ^^ no implementation for `&{integer} == {integer}`
29+
|
30+
= help: the trait `PartialEq<{integer}>` is not implemented for `&{integer}`
31+
= note: required for `&&{integer}` to implement `PartialEq<&{integer}>`
32+
help: consider dereferencing here
33+
|
34+
LL | _ = *foo == &0;
35+
| +
36+
37+
error[E0277]: can't compare `&&&&&&{integer}` with `{integer}`
38+
--> $DIR/binary-op-suggest-deref.rs:19:17
39+
|
40+
LL | _ = &&&&foo == 0;
41+
| ^^ no implementation for `&&&&&&{integer} == {integer}`
42+
|
43+
= help: the trait `PartialEq<{integer}>` is not implemented for `&&&&&&{integer}`
44+
help: consider removing the borrows and dereferencing instead
45+
|
46+
LL - _ = &&&&foo == 0;
47+
LL + _ = **foo == 0;
48+
|
49+
50+
error[E0277]: can't compare `&{integer}` with `{integer}`
51+
--> $DIR/binary-op-suggest-deref.rs:21:14
52+
|
53+
LL | _ = *foo == 0;
54+
| ^^ no implementation for `&{integer} == {integer}`
55+
|
56+
= help: the trait `PartialEq<{integer}>` is not implemented for `&{integer}`
57+
help: consider dereferencing here
58+
|
59+
LL | _ = **foo == 0;
60+
| +
61+
62+
error[E0277]: can't compare `&&{integer}` with `{integer}`
63+
--> $DIR/binary-op-suggest-deref.rs:23:15
64+
|
65+
LL | _ = &&foo == &&0;
66+
| ^^ no implementation for `&&{integer} == {integer}`
67+
|
68+
= help: the trait `PartialEq<{integer}>` is not implemented for `&&{integer}`
69+
= note: required for `&&&{integer}` to implement `PartialEq<&{integer}>`
70+
= note: 1 redundant requirement hidden
71+
= note: required for `&&&&{integer}` to implement `PartialEq<&&{integer}>`
72+
help: consider removing the borrows
73+
|
74+
LL - _ = &&foo == &&0;
75+
LL + _ = foo == &&0;
76+
|
77+
78+
error[E0277]: can't compare `&Box<{integer}>` with `{integer}`
79+
--> $DIR/binary-op-suggest-deref.rs:25:23
80+
|
81+
LL | _ = &Box::new(42) == 42;
82+
| ^^ no implementation for `&Box<{integer}> == {integer}`
83+
|
84+
= help: the trait `PartialEq<{integer}>` is not implemented for `&Box<{integer}>`
85+
help: consider removing the borrow and dereferencing instead
86+
|
87+
LL - _ = &Box::new(42) == 42;
88+
LL + _ = *Box::new(42) == 42;
89+
|
90+
91+
error[E0277]: can't compare `&Box<&Box<&{integer}>>` with `{integer}`
92+
--> $DIR/binary-op-suggest-deref.rs:27:35
93+
|
94+
LL | _ = &Box::new(&Box::new(&42)) == 42;
95+
| ^^ no implementation for `&Box<&Box<&{integer}>> == {integer}`
96+
|
97+
= help: the trait `PartialEq<{integer}>` is not implemented for `&Box<&Box<&{integer}>>`
98+
help: consider removing the borrow and dereferencing instead
99+
|
100+
LL - _ = &Box::new(&Box::new(&42)) == 42;
101+
LL + _ = ****Box::new(&Box::new(&42)) == 42;
102+
|
103+
104+
error[E0277]: can't compare `{integer}` with `&&{integer}`
105+
--> $DIR/binary-op-suggest-deref.rs:31:11
106+
|
107+
LL | _ = 0 == foo;
108+
| ^^ no implementation for `{integer} == &&{integer}`
109+
|
110+
= help: the trait `PartialEq<&&{integer}>` is not implemented for `{integer}`
111+
help: consider dereferencing here
112+
|
113+
LL | _ = 0 == **foo;
114+
| ++
115+
116+
error[E0277]: can't compare `{integer}` with `&{integer}`
117+
--> $DIR/binary-op-suggest-deref.rs:33:12
118+
|
119+
LL | _ = &0 == foo;
120+
| ^^ no implementation for `{integer} == &{integer}`
121+
|
122+
= help: the trait `PartialEq<&{integer}>` is not implemented for `{integer}`
123+
= note: required for `&{integer}` to implement `PartialEq<&&{integer}>`
124+
help: consider dereferencing here
125+
|
126+
LL | _ = &0 == *foo;
127+
| +
128+
129+
error[E0277]: can't compare `{integer}` with `&&&&&&{integer}`
130+
--> $DIR/binary-op-suggest-deref.rs:35:11
131+
|
132+
LL | _ = 0 == &&&&foo;
133+
| ^^ no implementation for `{integer} == &&&&&&{integer}`
134+
|
135+
= help: the trait `PartialEq<&&&&&&{integer}>` is not implemented for `{integer}`
136+
help: consider removing the borrows and dereferencing instead
137+
|
138+
LL - _ = 0 == &&&&foo;
139+
LL + _ = 0 == **foo;
140+
|
141+
142+
error[E0277]: can't compare `{integer}` with `&{integer}`
143+
--> $DIR/binary-op-suggest-deref.rs:37:11
144+
|
145+
LL | _ = 0 == *foo;
146+
| ^^ no implementation for `{integer} == &{integer}`
147+
|
148+
= help: the trait `PartialEq<&{integer}>` is not implemented for `{integer}`
149+
help: consider dereferencing here
150+
|
151+
LL | _ = 0 == **foo;
152+
| +
153+
154+
error[E0277]: can't compare `{integer}` with `&&{integer}`
155+
--> $DIR/binary-op-suggest-deref.rs:39:13
156+
|
157+
LL | _ = &&0 == &&foo;
158+
| ^^ no implementation for `{integer} == &&{integer}`
159+
|
160+
= help: the trait `PartialEq<&&{integer}>` is not implemented for `{integer}`
161+
= note: required for `&{integer}` to implement `PartialEq<&&&{integer}>`
162+
= note: 1 redundant requirement hidden
163+
= note: required for `&&{integer}` to implement `PartialEq<&&&&{integer}>`
164+
help: consider removing the borrows
165+
|
166+
LL - _ = &&0 == &&foo;
167+
LL + _ = &&0 == foo;
168+
|
169+
170+
error[E0277]: can't compare `Box<Box<{integer}>>` with `&&{integer}`
171+
--> $DIR/binary-op-suggest-deref.rs:43:33
172+
|
173+
LL | _ = &Box::new(Box::new(42)) == &foo;
174+
| ^^ no implementation for `Box<Box<{integer}>> == &&{integer}`
175+
|
176+
= help: the trait `PartialEq<&&{integer}>` is not implemented for `Box<Box<{integer}>>`
177+
= note: required for `&Box<Box<{integer}>>` to implement `PartialEq<&&&{integer}>`
178+
help: consider dereferencing both sides of the expression
179+
|
180+
LL - _ = &Box::new(Box::new(42)) == &foo;
181+
LL + _ = **Box::new(Box::new(42)) == **foo;
182+
|
183+
184+
error[E0277]: can't compare `Box<{integer}>` with `&&{integer}`
185+
--> $DIR/binary-op-suggest-deref.rs:45:23
186+
|
187+
LL | _ = &Box::new(42) == &foo;
188+
| ^^ no implementation for `Box<{integer}> == &&{integer}`
189+
|
190+
= help: the trait `PartialEq<&&{integer}>` is not implemented for `Box<{integer}>`
191+
= note: required for `&Box<{integer}>` to implement `PartialEq<&&&{integer}>`
192+
help: consider dereferencing both sides of the expression
193+
|
194+
LL - _ = &Box::new(42) == &foo;
195+
LL + _ = *Box::new(42) == **foo;
196+
|
197+
198+
error[E0277]: can't compare `Box<Box<Box<Box<{integer}>>>>` with `&&{integer}`
199+
--> $DIR/binary-op-suggest-deref.rs:47:53
200+
|
201+
LL | _ = &Box::new(Box::new(Box::new(Box::new(42)))) == &foo;
202+
| ^^ no implementation for `Box<Box<Box<Box<{integer}>>>> == &&{integer}`
203+
|
204+
= help: the trait `PartialEq<&&{integer}>` is not implemented for `Box<Box<Box<Box<{integer}>>>>`
205+
= note: required for `&Box<Box<Box<Box<{integer}>>>>` to implement `PartialEq<&&&{integer}>`
206+
help: consider dereferencing both sides of the expression
207+
|
208+
LL - _ = &Box::new(Box::new(Box::new(Box::new(42)))) == &foo;
209+
LL + _ = ****Box::new(Box::new(Box::new(Box::new(42)))) == **foo;
210+
|
211+
212+
error[E0277]: can't compare `&&{integer}` with `Box<Box<Box<Box<{integer}>>>>`
213+
--> $DIR/binary-op-suggest-deref.rs:49:14
214+
|
215+
LL | _ = &foo == &Box::new(Box::new(Box::new(Box::new(42))));
216+
| ^^ no implementation for `&&{integer} == Box<Box<Box<Box<{integer}>>>>`
217+
|
218+
= help: the trait `PartialEq<Box<Box<Box<Box<{integer}>>>>>` is not implemented for `&&{integer}`
219+
= note: required for `&&&{integer}` to implement `PartialEq<&Box<Box<Box<Box<{integer}>>>>>`
220+
help: consider dereferencing both sides of the expression
221+
|
222+
LL - _ = &foo == &Box::new(Box::new(Box::new(Box::new(42))));
223+
LL + _ = **foo == ****Box::new(Box::new(Box::new(Box::new(42))));
224+
|
225+
226+
error[E0308]: mismatched types
227+
--> $DIR/binary-op-suggest-deref.rs:53:25
228+
|
229+
LL | _ = Box::new(42) == 42;
230+
| ------------ ^^ expected `Box<{integer}>`, found integer
231+
| |
232+
| expected because this is `Box<{integer}>`
233+
|
234+
= note: expected struct `Box<{integer}>`
235+
found type `{integer}`
236+
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
237+
help: store this in the heap by calling `Box::new`
238+
|
239+
LL | _ = Box::new(42) == Box::new(42);
240+
| +++++++++ +
241+
242+
error[E0277]: can't compare `&&{integer}` with `Foo`
243+
--> $DIR/binary-op-suggest-deref.rs:58:13
244+
|
245+
LL | _ = &&0 == Foo;
246+
| ^^ no implementation for `&&{integer} == Foo`
247+
|
248+
= help: the trait `PartialEq<Foo>` is not implemented for `&&{integer}`
249+
= help: the following other types implement trait `PartialEq<Rhs>`:
250+
isize
251+
i8
252+
i16
253+
i32
254+
i64
255+
i128
256+
usize
257+
u8
258+
and 6 others
259+
260+
error[E0369]: binary operation `==` cannot be applied to type `Foo`
261+
--> $DIR/binary-op-suggest-deref.rs:60:13
262+
|
263+
LL | _ = Foo == &&0;
264+
| --- ^^ --- &&{integer}
265+
| |
266+
| Foo
267+
|
268+
note: an implementation of `PartialEq<&&{integer}>` might be missing for `Foo`
269+
--> $DIR/binary-op-suggest-deref.rs:57:5
270+
|
271+
LL | struct Foo;
272+
| ^^^^^^^^^^ must implement `PartialEq<&&{integer}>`
273+
help: consider annotating `Foo` with `#[derive(PartialEq)]`
274+
|
275+
LL + #[derive(PartialEq)]
276+
LL | struct Foo;
277+
|
278+
279+
error[E0277]: can't compare `&String` with `str`
280+
--> $DIR/binary-op-suggest-deref.rs:69:20
281+
|
282+
LL | _ = string_ref == partial[..3];
283+
| ^^ no implementation for `&String == str`
284+
|
285+
= help: the trait `PartialEq<str>` is not implemented for `&String`
286+
help: consider dereferencing here
287+
|
288+
LL | _ = *string_ref == partial[..3];
289+
| +
290+
291+
error[E0277]: can't compare `str` with `&String`
292+
--> $DIR/binary-op-suggest-deref.rs:71:22
293+
|
294+
LL | _ = partial[..3] == string_ref;
295+
| ^^ no implementation for `str == &String`
296+
|
297+
= help: the trait `PartialEq<&String>` is not implemented for `str`
298+
help: consider dereferencing here
299+
|
300+
LL | _ = partial[..3] == *string_ref;
301+
| +
302+
303+
error: aborting due to 22 previous errors
13304

14-
For more information about this error, try `rustc --explain E0308`.
305+
Some errors have detailed explanations: E0277, E0308, E0369.
306+
For more information about an error, try `rustc --explain E0277`.

‎tests/ui/dst/issue-113447.fixed

Lines changed: 0 additions & 25 deletions
This file was deleted.

‎tests/ui/dst/issue-113447.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// run-rustfix
2-
31
pub struct Bytes;
42

53
impl Bytes {

‎tests/ui/dst/issue-113447.stderr

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,15 @@
11
error[E0277]: can't compare `&[u8; 1]` with `[{integer}; 1]`
2-
--> $DIR/issue-113447.rs:24:20
2+
--> $DIR/issue-113447.rs:22:20
33
|
44
LL | let _ = &[0u8] == [0xAA];
55
| ^^ no implementation for `&[u8; 1] == [{integer}; 1]`
66
|
77
= help: the trait `PartialEq<[{integer}; 1]>` is not implemented for `&[u8; 1]`
8-
= help: the following other types implement trait `PartialEq<Rhs>`:
9-
<[A; N] as PartialEq<[B; N]>>
10-
<[A; N] as PartialEq<[B]>>
11-
<[A; N] as PartialEq<&[B]>>
12-
<[A; N] as PartialEq<&mut [B]>>
13-
<[T] as PartialEq<Vec<U, A>>>
14-
<[A] as PartialEq<[B]>>
15-
<[B] as PartialEq<[A; N]>>
16-
<&[u8] as PartialEq<Bytes>>
17-
and 4 others
18-
help: convert the array to a `&[u8]` slice instead
8+
help: consider removing the borrow
9+
|
10+
LL - let _ = &[0u8] == [0xAA];
11+
LL + let _ = [0u8] == [0xAA];
1912
|
20-
LL | let _ = &[0u8] == &[0xAA][..];
21-
| + ++++
2213

2314
error: aborting due to 1 previous error
2415

‎tests/ui/partialeq_help.stderr

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ LL | a == b;
55
| ^^ no implementation for `&T == T`
66
|
77
= help: the trait `PartialEq<T>` is not implemented for `&T`
8+
help: consider dereferencing here
9+
|
10+
LL | *a == b;
11+
| +
812
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
913
|
1014
LL | fn foo<T: PartialEq>(a: &T, b: T) where &T: PartialEq<T> {
@@ -17,6 +21,10 @@ LL | a == b;
1721
| ^^ no implementation for `&T == T`
1822
|
1923
= help: the trait `PartialEq<T>` is not implemented for `&T`
24+
help: consider dereferencing here
25+
|
26+
LL | *a == b;
27+
| +
2028
help: consider extending the `where` clause, but there might be an alternative better way to express this requirement
2129
|
2230
LL | fn foo2<T: PartialEq>(a: &T, b: T) where &T: PartialEq<T> {

0 commit comments

Comments
 (0)
Please sign in to comment.