Skip to content

Commit

Permalink
Make derive(Trait) suggestion more accurate
Browse files Browse the repository at this point in the history
Only suggest `derive(PartialEq)` when both LHS and RHS types
are the same, otherwise the suggestion is not useful.
  • Loading branch information
estebank committed Dec 27, 2023
1 parent a861c89 commit 105e206
Show file tree
Hide file tree
Showing 5 changed files with 12 additions and 16 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1662,7 +1662,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
self.suggest_derive(diag, &[(trait_ref.to_predicate(self.tcx), None, None)]);
self.suggest_derive(diag, &[(trait_ref.to_predicate(self.tcx), None, None)], true);
}
}
}
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -971,7 +971,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
"the following trait bounds were not satisfied:\n{bound_list}"
));
}
self.suggest_derive(&mut err, unsatisfied_predicates);
self.suggest_derive(&mut err, unsatisfied_predicates, true);

unsatisfied_bounds = true;
}
Expand Down Expand Up @@ -2252,6 +2252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
err: &mut Diagnostic,
errors: Vec<FulfillmentError<'tcx>>,
suggest_derive: bool,
) {
let all_local_types_needing_impls =
errors.iter().all(|e| match e.obligation.predicate.kind().skip_binder() {
Expand Down Expand Up @@ -2322,7 +2323,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.iter()
.map(|e| (e.obligation.predicate, None, Some(e.obligation.cause.clone())))
.collect();
self.suggest_derive(err, &preds);
self.suggest_derive(err, &preds, suggest_derive);
}

pub fn suggest_derive(
Expand All @@ -2333,6 +2334,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Option<ty::Predicate<'tcx>>,
Option<ObligationCause<'tcx>>,
)],
suggest_derive: bool,
) {
let mut derives = Vec::<(String, Span, Symbol)>::new();
let mut traits = Vec::new();
Expand Down Expand Up @@ -2419,6 +2421,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
);
}

if !suggest_derive {
return;
}
for (self_name, self_span, traits) in &derives_grouped {
err.span_suggestion_verbose(
self_span.shrink_to_lo(),
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_hir_typeck/src/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
lhs_expr.span,
format!("cannot use `{}=` on type `{}`", op.node.as_str(), lhs_ty),
);
self.note_unmet_impls_on_type(&mut err, errors);
self.note_unmet_impls_on_type(&mut err, errors, false);
(err, None)
}
IsAssign::No => {
Expand Down Expand Up @@ -375,7 +375,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.span_label(lhs_expr.span, lhs_ty.to_string());
err.span_label(rhs_expr.span, rhs_ty.to_string());
}
self.note_unmet_impls_on_type(&mut err, errors);
let suggest_derive = self.can_eq(self.param_env, lhs_ty, rhs_ty);
self.note_unmet_impls_on_type(&mut err, errors, suggest_derive);
(err, output_def_id)
}
};
Expand Down Expand Up @@ -852,7 +853,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Str | Never | Char | Tuple(_) | Array(_, _) => {}
Ref(_, lty, _) if *lty.kind() == Str => {}
_ => {
self.note_unmet_impls_on_type(&mut err, errors);
self.note_unmet_impls_on_type(&mut err, errors, true);
}
}
}
Expand Down
5 changes: 0 additions & 5 deletions tests/ui/binop/binary-op-suggest-deref.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -270,11 +270,6 @@ note: an implementation of `PartialEq<&&{integer}>` might be missing for `Foo`
|
LL | struct Foo;
| ^^^^^^^^^^ must implement `PartialEq<&&{integer}>`
help: consider annotating `Foo` with `#[derive(PartialEq)]`
|
LL + #[derive(PartialEq)]
LL | struct Foo;
|

error[E0277]: can't compare `&String` with `str`
--> $DIR/binary-op-suggest-deref.rs:69:20
Expand Down
5 changes: 0 additions & 5 deletions tests/ui/issues/issue-62375.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ note: an implementation of `PartialEq<fn(()) -> A {A::Value}>` might be missing
|
LL | enum A {
| ^^^^^^ must implement `PartialEq<fn(()) -> A {A::Value}>`
help: consider annotating `A` with `#[derive(PartialEq)]`
|
LL + #[derive(PartialEq)]
LL | enum A {
|
help: use parentheses to construct this tuple variant
|
LL | a == A::Value(/* () */);
Expand Down

0 comments on commit 105e206

Please sign in to comment.