Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 22a0e4f

Browse files
committed
Do not incorrectly suggest restricting implied bounds
When we have already suggested bounds that imply the about to be suggested bound, skip them.
1 parent 81ba427 commit 22a0e4f

File tree

3 files changed

+38
-16
lines changed

3 files changed

+38
-16
lines changed

compiler/rustc_hir_typeck/src/method/suggest.rs

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -505,19 +505,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
505505
}
506506
_ => None,
507507
};
508-
if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
509-
if let Some(g) = kind.generics() {
510-
let key = (
511-
g.tail_span_for_predicate_suggestion(),
512-
g.add_where_or_trailing_comma(),
513-
);
514-
type_params
515-
.entry(key)
516-
.or_insert_with(FxHashSet::default)
517-
.insert(obligation.to_owned());
518-
}
508+
if let Some(hir::Node::Item(hir::Item { kind, .. })) = node
509+
&& let Some(g) = kind.generics()
510+
{
511+
let key = (
512+
g.tail_span_for_predicate_suggestion(),
513+
g.add_where_or_trailing_comma(),
514+
);
515+
type_params
516+
.entry(key)
517+
.or_insert_with(FxHashSet::default)
518+
.insert(obligation.to_owned());
519+
return true;
519520
}
520521
}
522+
false
521523
};
522524
let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
523525
let msg = format!(
@@ -732,19 +734,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
732734
unsatisfied_bounds = true;
733735
}
734736

737+
let mut suggested_bounds = FxHashSet::default();
735738
// The requirements that didn't have an `impl` span to show.
736739
let mut bound_list = unsatisfied_predicates
737740
.iter()
738741
.filter_map(|(pred, parent_pred, _cause)| {
742+
let mut suggested = false;
739743
format_pred(*pred).map(|(p, self_ty)| {
740-
collect_type_param_suggestions(self_ty, *pred, &p);
744+
if let Some(parent) = parent_pred && suggested_bounds.contains(parent) {
745+
// We don't suggest `PartialEq` when we already suggest `Eq`.
746+
} else if !suggested_bounds.contains(pred) {
747+
if collect_type_param_suggestions(self_ty, *pred, &p) {
748+
suggested = true;
749+
suggested_bounds.insert(pred);
750+
}
751+
}
741752
(
742753
match parent_pred {
743754
None => format!("`{}`", &p),
744755
Some(parent_pred) => match format_pred(*parent_pred) {
745756
None => format!("`{}`", &p),
746757
Some((parent_p, _)) => {
747-
collect_type_param_suggestions(self_ty, *parent_pred, &p);
758+
if !suggested
759+
&& !suggested_bounds.contains(pred)
760+
&& !suggested_bounds.contains(parent_pred)
761+
{
762+
if collect_type_param_suggestions(
763+
self_ty,
764+
*parent_pred,
765+
&p,
766+
) {
767+
suggested_bounds.insert(pred);
768+
}
769+
}
748770
format!("`{}`\nwhich is required by `{}`", p, parent_p)
749771
}
750772
},

tests/ui/missing-trait-bounds/issue-35677.fixed

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::collections::HashSet;
44
use std::hash::Hash;
55

6-
fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash, T: PartialEq {
6+
fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash {
77
this.is_subset(other)
88
//~^ ERROR the method
99
}

tests/ui/missing-trait-bounds/issue-35677.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ LL | this.is_subset(other)
1111
`T: Hash`
1212
help: consider restricting the type parameters to satisfy the trait bounds
1313
|
14-
LL | fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash, T: PartialEq {
15-
| ++++++++++++++++++++++++++++++++++
14+
LL | fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash {
15+
| ++++++++++++++++++++
1616

1717
error: aborting due to previous error
1818

0 commit comments

Comments
 (0)