1
Fork 0

diagnostics: do not spurriously claim something is "not an iterator"

Fixes a minor regression caused by #94746, where iter::Filter is
spurriously declared "not an iterator."
This commit is contained in:
Michael Howell 2022-03-11 16:58:14 -07:00
parent 335ffbfa54
commit 317f684160
3 changed files with 22 additions and 4 deletions

View file

@ -574,6 +574,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Pick out the list of unimplemented traits on the receiver.
// This is used for custom error messages with the `#[rustc_on_unimplemented]` attribute.
let mut unimplemented_traits = FxHashMap::default();
let mut unimplemented_traits_only = true;
for (predicate, _parent_pred, cause) in &unsatisfied_predicates {
if let (ty::PredicateKind::Trait(p), Some(cause)) =
(predicate.kind().skip_binder(), cause.as_ref())
@ -596,6 +597,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
// Make sure that, if any traits other than the found ones were involved,
// we don't don't report an unimplemented trait.
// We don't want to say that `iter::Cloned` is not an interator, just
// because of some non-Clone item being iterated over.
for (predicate, _parent_pred, _cause) in &unsatisfied_predicates {
match predicate.kind().skip_binder() {
ty::PredicateKind::Trait(p)
if unimplemented_traits.contains_key(&p.trait_ref.def_id) => {}
_ => {
unimplemented_traits_only = false;
break;
}
}
}
let mut collect_type_param_suggestions =
|self_ty: Ty<'tcx>, parent_pred: ty::Predicate<'tcx>, obligation: &str| {
// We don't care about regions here, so it's fine to skip the binder here.
@ -839,7 +855,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.join("\n");
let actual_prefix = actual.prefix_string(self.tcx);
info!("unimplemented_traits.len() == {}", unimplemented_traits.len());
let (primary_message, label) = if unimplemented_traits.len() == 1 {
let (primary_message, label) = if unimplemented_traits.len() == 1
&& unimplemented_traits_only
{
unimplemented_traits
.into_iter()
.next()