about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-03-12 11:58:07 +0000
committerbors <bors@rust-lang.org>2022-03-12 11:58:07 +0000
commit258256697b8550860be0f6194dec532ac616c2c1 (patch)
tree5224b20c3c32a81d3a24fe83a577f4aec2be4d3e
parentf8a29bd95e0427ea1a46412ee2bb48e92644edc9 (diff)
parent317f6841605a8166e3db28a2a40c457c1a599f1f (diff)
downloadrust-258256697b8550860be0f6194dec532ac616c2c1.tar.gz
rust-258256697b8550860be0f6194dec532ac616c2c1.zip
Auto merge of #94870 - notriddle:notriddle/filter-regression, r=oli-obk
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."
-rw-r--r--compiler/rustc_typeck/src/check/method/suggest.rs20
-rw-r--r--src/test/ui/mismatched_types/issue-36053-2.rs2
-rw-r--r--src/test/ui/mismatched_types/issue-36053-2.stderr4
3 files changed, 22 insertions, 4 deletions
diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs
index c024f5b42e4..715671dd452 100644
--- a/compiler/rustc_typeck/src/check/method/suggest.rs
+++ b/compiler/rustc_typeck/src/check/method/suggest.rs
@@ -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()
diff --git a/src/test/ui/mismatched_types/issue-36053-2.rs b/src/test/ui/mismatched_types/issue-36053-2.rs
index 0252ba2eb04..17d2292baaf 100644
--- a/src/test/ui/mismatched_types/issue-36053-2.rs
+++ b/src/test/ui/mismatched_types/issue-36053-2.rs
@@ -5,6 +5,6 @@
 use std::iter::once;
 fn main() {
     once::<&str>("str").fuse().filter(|a: &str| true).count();
-    //~^ ERROR not an iterator
+    //~^ ERROR the method
     //~| ERROR type mismatch in closure arguments
 }
diff --git a/src/test/ui/mismatched_types/issue-36053-2.stderr b/src/test/ui/mismatched_types/issue-36053-2.stderr
index b1010171eb2..a8bcdf5efe9 100644
--- a/src/test/ui/mismatched_types/issue-36053-2.stderr
+++ b/src/test/ui/mismatched_types/issue-36053-2.stderr
@@ -12,11 +12,11 @@ note: required by a bound in `filter`
 LL |         P: FnMut(&Self::Item) -> bool,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `filter`
 
-error[E0599]: `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>` is not an iterator
+error[E0599]: the method `count` exists for struct `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>`, but its trait bounds were not satisfied
   --> $DIR/issue-36053-2.rs:7:55
    |
 LL |     once::<&str>("str").fuse().filter(|a: &str| true).count();
-   |                                       --------------  ^^^^^ `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>` is not an iterator
+   |                                       --------------  ^^^^^ method cannot be called on `Filter<Fuse<std::iter::Once<&str>>, [closure@$DIR/issue-36053-2.rs:7:39: 7:53]>` due to unsatisfied trait bounds
    |                                       |
    |                                       doesn't satisfy `<_ as FnOnce<(&&str,)>>::Output = bool`
    |                                       doesn't satisfy `_: FnMut<(&&str,)>`