Skip to content

Commit 105e206

Browse files
committed
Make derive(Trait) suggestion more accurate
Only suggest `derive(PartialEq)` when both LHS and RHS types are the same, otherwise the suggestion is not useful.
1 parent a861c89 commit 105e206

File tree

5 files changed

+12
-16
lines changed

5 files changed

+12
-16
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1662,7 +1662,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
16621662
}
16631663
}
16641664
}
1665-
self.suggest_derive(diag, &[(trait_ref.to_predicate(self.tcx), None, None)]);
1665+
self.suggest_derive(diag, &[(trait_ref.to_predicate(self.tcx), None, None)], true);
16661666
}
16671667
}
16681668
}

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -971,7 +971,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
971971
"the following trait bounds were not satisfied:\n{bound_list}"
972972
));
973973
}
974-
self.suggest_derive(&mut err, unsatisfied_predicates);
974+
self.suggest_derive(&mut err, unsatisfied_predicates, true);
975975

976976
unsatisfied_bounds = true;
977977
}
@@ -2252,6 +2252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
22522252
&self,
22532253
err: &mut Diagnostic,
22542254
errors: Vec<FulfillmentError<'tcx>>,
2255+
suggest_derive: bool,
22552256
) {
22562257
let all_local_types_needing_impls =
22572258
errors.iter().all(|e| match e.obligation.predicate.kind().skip_binder() {
@@ -2322,7 +2323,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23222323
.iter()
23232324
.map(|e| (e.obligation.predicate, None, Some(e.obligation.cause.clone())))
23242325
.collect();
2325-
self.suggest_derive(err, &preds);
2326+
self.suggest_derive(err, &preds, suggest_derive);
23262327
}
23272328

23282329
pub fn suggest_derive(
@@ -2333,6 +2334,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
23332334
Option<ty::Predicate<'tcx>>,
23342335
Option<ObligationCause<'tcx>>,
23352336
)],
2337+
suggest_derive: bool,
23362338
) {
23372339
let mut derives = Vec::<(String, Span, Symbol)>::new();
23382340
let mut traits = Vec::new();
@@ -2419,6 +2421,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
24192421
);
24202422
}
24212423

2424+
if !suggest_derive {
2425+
return;
2426+
}
24222427
for (self_name, self_span, traits) in &derives_grouped {
24232428
err.span_suggestion_verbose(
24242429
self_span.shrink_to_lo(),

compiler/rustc_hir_typeck/src/op.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
318318
lhs_expr.span,
319319
format!("cannot use `{}=` on type `{}`", op.node.as_str(), lhs_ty),
320320
);
321-
self.note_unmet_impls_on_type(&mut err, errors);
321+
self.note_unmet_impls_on_type(&mut err, errors, false);
322322
(err, None)
323323
}
324324
IsAssign::No => {
@@ -375,7 +375,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
375375
err.span_label(lhs_expr.span, lhs_ty.to_string());
376376
err.span_label(rhs_expr.span, rhs_ty.to_string());
377377
}
378-
self.note_unmet_impls_on_type(&mut err, errors);
378+
let suggest_derive = self.can_eq(self.param_env, lhs_ty, rhs_ty);
379+
self.note_unmet_impls_on_type(&mut err, errors, suggest_derive);
379380
(err, output_def_id)
380381
}
381382
};
@@ -852,7 +853,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
852853
Str | Never | Char | Tuple(_) | Array(_, _) => {}
853854
Ref(_, lty, _) if *lty.kind() == Str => {}
854855
_ => {
855-
self.note_unmet_impls_on_type(&mut err, errors);
856+
self.note_unmet_impls_on_type(&mut err, errors, true);
856857
}
857858
}
858859
}

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,6 @@ note: an implementation of `PartialEq<&&{integer}>` might be missing for `Foo`
270270
|
271271
LL | struct Foo;
272272
| ^^^^^^^^^^ must implement `PartialEq<&&{integer}>`
273-
help: consider annotating `Foo` with `#[derive(PartialEq)]`
274-
|
275-
LL + #[derive(PartialEq)]
276-
LL | struct Foo;
277-
|
278273

279274
error[E0277]: can't compare `&String` with `str`
280275
--> $DIR/binary-op-suggest-deref.rs:69:20

tests/ui/issues/issue-62375.stderr

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ note: an implementation of `PartialEq<fn(()) -> A {A::Value}>` might be missing
1111
|
1212
LL | enum A {
1313
| ^^^^^^ must implement `PartialEq<fn(()) -> A {A::Value}>`
14-
help: consider annotating `A` with `#[derive(PartialEq)]`
15-
|
16-
LL + #[derive(PartialEq)]
17-
LL | enum A {
18-
|
1914
help: use parentheses to construct this tuple variant
2015
|
2116
LL | a == A::Value(/* () */);

0 commit comments

Comments
 (0)