about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2022-12-07 14:16:37 -0800
committerEsteban Küber <esteban@kuber.com.ar>2022-12-11 09:46:02 -0800
commit78f97595a3e7ef9d796b77cd5572676a1a41fb71 (patch)
tree26d43ff8c0f9ff4e2566872707b5d449749b9cf6
parentaff0ab43c8fecbf9473d60d30e5d03f8612efd91 (diff)
downloadrust-78f97595a3e7ef9d796b77cd5572676a1a41fb71.tar.gz
rust-78f97595a3e7ef9d796b77cd5572676a1a41fb71.zip
Only point at methods that might be relevant
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs19
-rw-r--r--src/test/ui/issues/issue-34334.stderr4
-rw-r--r--src/test/ui/iterators/invalid-iterator-chain.rs10
-rw-r--r--src/test/ui/iterators/invalid-iterator-chain.stderr67
4 files changed, 81 insertions, 19 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 1d6e749b9e3..cfd7c20767f 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -3008,7 +3008,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             let Some(prev_assoc_in_method) = assocs.peek() else {
                                 for entry in assocs_in_method {
                                     let Some((span, (assoc, ty))) = entry else { continue; };
-                                    primary_spans.push(span);
+                                    if type_diffs.iter().any(|diff| {
+                                        let Sorts(expected_found) = diff else { return false; };
+                                        self.can_eq(param_env, expected_found.found, ty).is_ok()
+                                    }) {
+                                        // FIXME: this doesn't quite work for `Iterator::collect`
+                                        // because we have `Vec<i32>` and `()`, but we'd want `i32`
+                                        // to point at the `.into_iter()` call, but as long as we
+                                        // still point at the other method calls that might have
+                                        // introduced the issue, this is fine for now.
+                                        primary_spans.push(span);
+                                    }
                                     span_labels.push((
                                         span,
                                         format!("`{assoc}` is `{ty}` here"),
@@ -3022,7 +3032,12 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 match (entry, prev_entry) {
                                     (Some((span, (assoc, ty))), Some((_, (_, prev_ty)))) => {
                                         if ty != *prev_ty {
-                                            primary_spans.push(span);
+                                            if type_diffs.iter().any(|diff| {
+                                                let Sorts(expected_found) = diff else { return false; };
+                                                self.can_eq(param_env, expected_found.found, ty).is_ok()
+                                            }) {
+                                                primary_spans.push(span);
+                                            }
                                             span_labels.push((
                                                 span,
                                                 format!("`{assoc}` changed to `{ty}` here"),
diff --git a/src/test/ui/issues/issue-34334.stderr b/src/test/ui/issues/issue-34334.stderr
index ac3b3e95faf..688a532adc6 100644
--- a/src/test/ui/issues/issue-34334.stderr
+++ b/src/test/ui/issues/issue-34334.stderr
@@ -23,13 +23,13 @@ LL |     let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_rece
    = help: the trait `FromIterator<()>` is not implemented for `Vec<(u32, _, _)>`
    = help: the trait `FromIterator<T>` is implemented for `Vec<T>`
 note: the method call chain might not have had the expected associated types
-  --> $DIR/issue-34334.rs:5:36
+  --> $DIR/issue-34334.rs:5:43
    |
 LL |     let sr: Vec<(u32, _, _) = vec![];
    |                               ------ this expression has type `Vec<(_, _, _)>`
 ...
 LL |     let sr2: Vec<(u32, _, _)> = sr.iter().map(|(faction, th_sender, th_receiver)| {}).collect();
-   |                                    ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::iter::Iterator::Item` changed to `()` here
+   |                                    ------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::iter::Iterator::Item` changed to `()` here
    |                                    |
    |                                    `std::iter::Iterator::Item` is `&(_, _, _)` here
 note: required by a bound in `collect`
diff --git a/src/test/ui/iterators/invalid-iterator-chain.rs b/src/test/ui/iterators/invalid-iterator-chain.rs
index e17b471b692..32141bf0fb8 100644
--- a/src/test/ui/iterators/invalid-iterator-chain.rs
+++ b/src/test/ui/iterators/invalid-iterator-chain.rs
@@ -17,6 +17,16 @@ fn main() {
             .map(|x| { x; })
             .sum::<i32>(),
     );
+    println!(
+        "{}",
+        vec![0, 1] //~ ERROR E0277
+            .iter()
+            .map(|x| x * 2)
+            .map(|x| x as f64)
+            .filter(|x| *x > 0.0)
+            .map(|x| { x + 1.0 })
+            .sum::<i32>(),
+    );
     println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>()); //~ ERROR E0277
     println!("{}", vec![(), ()].iter().sum::<i32>()); //~ ERROR E0277
     let a = vec![0];
diff --git a/src/test/ui/iterators/invalid-iterator-chain.stderr b/src/test/ui/iterators/invalid-iterator-chain.stderr
index 14e430726f6..55788ae80e6 100644
--- a/src/test/ui/iterators/invalid-iterator-chain.stderr
+++ b/src/test/ui/iterators/invalid-iterator-chain.stderr
@@ -10,12 +10,12 @@ LL |     println!("{}", scores.sum::<i32>());
              <i32 as Sum<&'a i32>>
              <i32 as Sum>
 note: the method call chain might not have had the expected associated types
-  --> $DIR/invalid-iterator-chain.rs:3:10
+  --> $DIR/invalid-iterator-chain.rs:4:10
    |
 LL |       let scores = vec![(0, 0)]
    |                    ------------ this expression has type `Vec<({integer}, {integer})>`
 LL |           .iter()
-   |            ^^^^^^ `std::iter::Iterator::Item` is `&({integer}, {integer})` here
+   |            ------ `std::iter::Iterator::Item` is `&({integer}, {integer})` here
 LL |           .map(|(a, b)| {
    |  __________^
 LL | |             a + b;
@@ -45,18 +45,18 @@ LL |               .sum::<i32>(),
              <i32 as Sum<&'a i32>>
              <i32 as Sum>
 note: the method call chain might not have had the expected associated types
-  --> $DIR/invalid-iterator-chain.rs:11:14
+  --> $DIR/invalid-iterator-chain.rs:12:14
    |
 LL |         vec![0, 1]
    |         ---------- this expression has type `Vec<{integer}>`
 LL |             .iter()
-   |              ^^^^^^ `std::iter::Iterator::Item` is `&{integer}` here
+   |              ------ `std::iter::Iterator::Item` is `&{integer}` here
 LL |             .map(|x| x * 2)
    |              ^^^^^^^^^^^^^^ `std::iter::Iterator::Item` changed to `{integer}` here
 LL |             .map(|x| x as f64)
-   |              ^^^^^^^^^^^^^^^^^ `std::iter::Iterator::Item` changed to `f64` here
+   |              ----------------- `std::iter::Iterator::Item` changed to `f64` here
 LL |             .map(|x| x as i64)
-   |              ^^^^^^^^^^^^^^^^^ `std::iter::Iterator::Item` changed to `i64` here
+   |              ----------------- `std::iter::Iterator::Item` changed to `i64` here
 LL |             .filter(|x| *x > 0)
    |              ------------------ `std::iter::Iterator::Item` remains `i64` here
 LL |             .map(|x| { x + 1 })
@@ -69,8 +69,45 @@ note: required by a bound in `std::iter::Iterator::sum`
 LL |         S: Sum<Self::Item>,
    |            ^^^^^^^^^^^^^^^ required by this bound in `std::iter::Iterator::sum`
 
+error[E0277]: the trait bound `i32: Sum<f64>` is not satisfied
+  --> $DIR/invalid-iterator-chain.rs:22:9
+   |
+LL | /         vec![0, 1]
+LL | |             .iter()
+LL | |             .map(|x| x * 2)
+LL | |             .map(|x| x as f64)
+LL | |             .filter(|x| *x > 0.0)
+LL | |             .map(|x| { x + 1.0 })
+   | |_________________________________^ the trait `Sum<f64>` is not implemented for `i32`
+LL |               .sum::<i32>(),
+   |                --- required by a bound introduced by this call
+   |
+   = help: the following other types implement trait `Sum<A>`:
+             <i32 as Sum<&'a i32>>
+             <i32 as Sum>
+note: the method call chain might not have had the expected associated types
+  --> $DIR/invalid-iterator-chain.rs:24:14
+   |
+LL |         vec![0, 1]
+   |         ---------- this expression has type `Vec<{integer}>`
+LL |             .iter()
+   |              ------ `std::iter::Iterator::Item` is `&{integer}` here
+LL |             .map(|x| x * 2)
+   |              ^^^^^^^^^^^^^^ `std::iter::Iterator::Item` changed to `{integer}` here
+LL |             .map(|x| x as f64)
+   |              ^^^^^^^^^^^^^^^^^ `std::iter::Iterator::Item` changed to `f64` here
+LL |             .filter(|x| *x > 0.0)
+   |              -------------------- `std::iter::Iterator::Item` remains `f64` here
+LL |             .map(|x| { x + 1.0 })
+   |              -------------------- `std::iter::Iterator::Item` remains `f64` here
+note: required by a bound in `std::iter::Iterator::sum`
+  --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
+   |
+LL |         S: Sum<Self::Item>,
+   |            ^^^^^^^^^^^^^^^ required by this bound in `std::iter::Iterator::sum`
+
 error[E0277]: the trait bound `i32: Sum<()>` is not satisfied
-  --> $DIR/invalid-iterator-chain.rs:20:20
+  --> $DIR/invalid-iterator-chain.rs:30:20
    |
 LL |     println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --- required by a bound introduced by this call
@@ -81,10 +118,10 @@ LL |     println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
              <i32 as Sum<&'a i32>>
              <i32 as Sum>
 note: the method call chain might not have had the expected associated types
-  --> $DIR/invalid-iterator-chain.rs:20:31
+  --> $DIR/invalid-iterator-chain.rs:30:38
    |
 LL |     println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
-   |                    ---------- ^^^^^^ ^^^^^^^^^^^^^^^ `std::iter::Iterator::Item` changed to `()` here
+   |                    ---------- ------ ^^^^^^^^^^^^^^^ `std::iter::Iterator::Item` changed to `()` here
    |                    |          |
    |                    |          `std::iter::Iterator::Item` is `&{integer}` here
    |                    this expression has type `Vec<{integer}>`
@@ -95,7 +132,7 @@ LL |         S: Sum<Self::Item>,
    |            ^^^^^^^^^^^^^^^ required by this bound in `std::iter::Iterator::sum`
 
 error[E0277]: the trait bound `i32: Sum<&()>` is not satisfied
-  --> $DIR/invalid-iterator-chain.rs:21:20
+  --> $DIR/invalid-iterator-chain.rs:31:20
    |
 LL |     println!("{}", vec![(), ()].iter().sum::<i32>());
    |                    ^^^^^^^^^^^^^^^^^^^ --- required by a bound introduced by this call
@@ -106,7 +143,7 @@ LL |     println!("{}", vec![(), ()].iter().sum::<i32>());
              <i32 as Sum<&'a i32>>
              <i32 as Sum>
 note: the method call chain might not have had the expected associated types
-  --> $DIR/invalid-iterator-chain.rs:21:33
+  --> $DIR/invalid-iterator-chain.rs:31:33
    |
 LL |     println!("{}", vec![(), ()].iter().sum::<i32>());
    |                    ------------ ^^^^^^ `std::iter::Iterator::Item` is `&()` here
@@ -119,7 +156,7 @@ LL |         S: Sum<Self::Item>,
    |            ^^^^^^^^^^^^^^^ required by this bound in `std::iter::Iterator::sum`
 
 error[E0277]: a value of type `Vec<i32>` cannot be built from an iterator over elements of type `()`
-  --> $DIR/invalid-iterator-chain.rs:30:23
+  --> $DIR/invalid-iterator-chain.rs:40:23
    |
 LL |     let g: Vec<i32> = f.collect();
    |                       ^ ------- required by a bound introduced by this call
@@ -129,12 +166,12 @@ LL |     let g: Vec<i32> = f.collect();
    = help: the trait `FromIterator<()>` is not implemented for `Vec<i32>`
    = help: the trait `FromIterator<T>` is implemented for `Vec<T>`
 note: the method call chain might not have had the expected associated types
-  --> $DIR/invalid-iterator-chain.rs:23:15
+  --> $DIR/invalid-iterator-chain.rs:36:15
    |
 LL |       let a = vec![0];
    |               ------- this expression has type `Vec<{integer}>`
 LL |       let b = a.into_iter();
-   |                 ^^^^^^^^^^^ `std::iter::Iterator::Item` is `{integer}` here
+   |                 ----------- `std::iter::Iterator::Item` is `{integer}` here
 LL |       let c = b.map(|x| x + 1);
    |                 -------------- `std::iter::Iterator::Item` remains `{integer}` here
 LL |       let d = c.filter(|x| *x > 10 );
@@ -152,6 +189,6 @@ note: required by a bound in `collect`
 LL |     fn collect<B: FromIterator<Self::Item>>(self) -> B
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect`
 
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0277`.