Skip to content

Commit

Permalink
Do not incorrectly suggest restricting implied bounds
Browse files Browse the repository at this point in the history
When we have already suggested bounds that imply the about to be
suggested bound, skip them.
  • Loading branch information
estebank committed Jan 13, 2023
1 parent 81ba427 commit 22a0e4f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 16 deletions.
48 changes: 35 additions & 13 deletions compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,19 +505,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
_ => None,
};
if let Some(hir::Node::Item(hir::Item { kind, .. })) = node {
if let Some(g) = kind.generics() {
let key = (
g.tail_span_for_predicate_suggestion(),
g.add_where_or_trailing_comma(),
);
type_params
.entry(key)
.or_insert_with(FxHashSet::default)
.insert(obligation.to_owned());
}
if let Some(hir::Node::Item(hir::Item { kind, .. })) = node
&& let Some(g) = kind.generics()
{
let key = (
g.tail_span_for_predicate_suggestion(),
g.add_where_or_trailing_comma(),
);
type_params
.entry(key)
.or_insert_with(FxHashSet::default)
.insert(obligation.to_owned());
return true;
}
}
false
};
let mut bound_span_label = |self_ty: Ty<'_>, obligation: &str, quiet: &str| {
let msg = format!(
Expand Down Expand Up @@ -732,19 +734,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
unsatisfied_bounds = true;
}

let mut suggested_bounds = FxHashSet::default();
// The requirements that didn't have an `impl` span to show.
let mut bound_list = unsatisfied_predicates
.iter()
.filter_map(|(pred, parent_pred, _cause)| {
let mut suggested = false;
format_pred(*pred).map(|(p, self_ty)| {
collect_type_param_suggestions(self_ty, *pred, &p);
if let Some(parent) = parent_pred && suggested_bounds.contains(parent) {
// We don't suggest `PartialEq` when we already suggest `Eq`.
} else if !suggested_bounds.contains(pred) {
if collect_type_param_suggestions(self_ty, *pred, &p) {
suggested = true;
suggested_bounds.insert(pred);
}
}
(
match parent_pred {
None => format!("`{}`", &p),
Some(parent_pred) => match format_pred(*parent_pred) {
None => format!("`{}`", &p),
Some((parent_p, _)) => {
collect_type_param_suggestions(self_ty, *parent_pred, &p);
if !suggested
&& !suggested_bounds.contains(pred)
&& !suggested_bounds.contains(parent_pred)
{
if collect_type_param_suggestions(
self_ty,
*parent_pred,
&p,
) {
suggested_bounds.insert(pred);
}
}
format!("`{}`\nwhich is required by `{}`", p, parent_p)
}
},
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/missing-trait-bounds/issue-35677.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use std::collections::HashSet;
use std::hash::Hash;

fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash, T: PartialEq {
fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash {
this.is_subset(other)
//~^ ERROR the method
}
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/missing-trait-bounds/issue-35677.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ LL | this.is_subset(other)
`T: Hash`
help: consider restricting the type parameters to satisfy the trait bounds
|
LL | fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash, T: PartialEq {
| ++++++++++++++++++++++++++++++++++
LL | fn is_subset<T>(this: &HashSet<T>, other: &HashSet<T>) -> bool where T: Eq, T: Hash {
| ++++++++++++++++++++

error: aborting due to previous error

Expand Down

0 comments on commit 22a0e4f

Please sign in to comment.