Skip to content

Point out the type of associated types in every method call of iterator chains #105332

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Dec 13, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|err| {
self.note_obligation_cause_code(
err,
&predicate,
predicate,
obligation.param_env,
obligation.cause.code(),
&mut vec![],
Expand Down Expand Up @@ -1586,7 +1586,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
{
self.note_obligation_cause_code(
&mut diag,
&error.obligation.predicate,
error.obligation.predicate,
error.obligation.param_env,
code,
&mut vec![],
Expand Down Expand Up @@ -2601,7 +2601,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if !self.maybe_note_obligation_cause_for_async_await(err, obligation) {
self.note_obligation_cause_code(
err,
&obligation.predicate,
obligation.predicate,
obligation.param_env,
obligation.cause.code(),
&mut vec![],
Expand Down
388 changes: 352 additions & 36 deletions compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ LL | let p = Some(45).and_then({
LL | |
LL | | |x| println!("doubling {}", x);
LL | | Some(x * 2)
| | ----------- this tail expression is of type `std::option::Option<_>`
| | ----------- this tail expression is of type `Option<_>`
LL | |
LL | | });
| |_____^ expected an `FnOnce<({integer},)>` closure, found `Option<_>`
Expand Down
10 changes: 10 additions & 0 deletions src/test/ui/issues/issue-34334.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,16 @@ 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: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();
| ------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `Iterator::Item` changed to `()` here
| |
| `Iterator::Item` is `&(_, _, _)` here
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
Expand Down
15 changes: 15 additions & 0 deletions src/test/ui/issues/issue-66923-show-error-for-correct-call.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ LL | let x2: Vec<f64> = x1.into_iter().collect();
|
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
= 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-66923-show-error-for-correct-call.rs:8:27
|
LL | let x1: &[f64] = &v;
| -- this expression has type `&Vec<f64>`
LL | let x2: Vec<f64> = x1.into_iter().collect();
| ^^^^^^^^^^^ `Iterator::Item` is `&f64` here
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
Expand All @@ -24,6 +31,14 @@ LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
|
= help: the trait `FromIterator<&f64>` is not implemented for `Vec<f64>`
= 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-66923-show-error-for-correct-call.rs:12:17
|
LL | let x1: &[f64] = &v;
| -- this expression has type `&Vec<f64>`
...
LL | let x3 = x1.into_iter().collect::<Vec<f64>>();
| ^^^^^^^^^^^ `Iterator::Item` is `&f64` here
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
Expand Down
41 changes: 41 additions & 0 deletions src/test/ui/iterators/invalid-iterator-chain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
fn main() {
let scores = vec![(0, 0)]
.iter()
.map(|(a, b)| {
a + b;
});
println!("{}", scores.sum::<i32>()); //~ ERROR E0277
println!(
"{}",
vec![0, 1] //~ ERROR E0277
.iter()
.map(|x| x * 2)
.map(|x| x as f64)
.map(|x| x as i64)
.filter(|x| *x > 0)
.map(|x| { x + 1 })
.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];
let b = a.into_iter();
let c = b.map(|x| x + 1);
let d = c.filter(|x| *x > 10 );
let e = d.map(|x| {
x + 1;
});
let f = e.filter(|_| false);
let g: Vec<i32> = f.collect(); //~ ERROR E0277
}
199 changes: 199 additions & 0 deletions src/test/ui/iterators/invalid-iterator-chain.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
--> $DIR/invalid-iterator-chain.rs:7:20
|
LL | println!("{}", scores.sum::<i32>());
| ^^^^^^ --- required by a bound introduced by this call
| |
| value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
|
= help: the trait `Sum<()>` is not implemented for `i32`
= 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:4:10
|
LL | let scores = vec![(0, 0)]
| ------------ this expression has type `Vec<({integer}, {integer})>`
LL | .iter()
| ------ `Iterator::Item` is `&({integer}, {integer})` here
LL | .map(|(a, b)| {
| __________^
LL | | a + b;
LL | | });
| |__________^ `Iterator::Item` changed to `()` 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 `Iterator::sum`

error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
--> $DIR/invalid-iterator-chain.rs:10:9
|
LL | / vec![0, 1]
LL | | .iter()
LL | | .map(|x| x * 2)
LL | | .map(|x| x as f64)
... |
LL | | .map(|x| { x + 1 })
LL | | .map(|x| { x; })
| |____________________________^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
LL | .sum::<i32>(),
| --- required by a bound introduced by this call
|
= help: the trait `Sum<()>` is not implemented for `i32`
= 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:12:14
|
LL | vec![0, 1]
| ---------- this expression has type `Vec<{integer}>`
LL | .iter()
| ------ `Iterator::Item` is `&{integer}` here
LL | .map(|x| x * 2)
| ^^^^^^^^^^^^^^ `Iterator::Item` changed to `{integer}` here
LL | .map(|x| x as f64)
| ----------------- `Iterator::Item` changed to `f64` here
LL | .map(|x| x as i64)
| ----------------- `Iterator::Item` changed to `i64` here
LL | .filter(|x| *x > 0)
| ------------------ `Iterator::Item` remains `i64` here
LL | .map(|x| { x + 1 })
| ------------------ `Iterator::Item` remains `i64` here
LL | .map(|x| { x; })
| ^^^^^^^^^^^^^^^ `Iterator::Item` changed to `()` 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 `Iterator::sum`

error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `f64`
--> $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 })
| |_________________________________^ value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=f64>`
LL | .sum::<i32>(),
| --- required by a bound introduced by this call
|
= help: the trait `Sum<f64>` is not implemented for `i32`
= 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()
| ------ `Iterator::Item` is `&{integer}` here
LL | .map(|x| x * 2)
| ^^^^^^^^^^^^^^ `Iterator::Item` changed to `{integer}` here
LL | .map(|x| x as f64)
| ^^^^^^^^^^^^^^^^^ `Iterator::Item` changed to `f64` here
LL | .filter(|x| *x > 0.0)
| -------------------- `Iterator::Item` remains `f64` here
LL | .map(|x| { x + 1.0 })
| -------------------- `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 `Iterator::sum`

error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `()`
--> $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
| |
| value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=()>`
|
= help: the trait `Sum<()>` is not implemented for `i32`
= 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:30:38
|
LL | println!("{}", vec![0, 1].iter().map(|x| { x; }).sum::<i32>());
| ---------- ------ ^^^^^^^^^^^^^^^ `Iterator::Item` changed to `()` here
| | |
| | `Iterator::Item` is `&{integer}` here
| this expression has type `Vec<{integer}>`
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 `Iterator::sum`

error[E0277]: a value of type `i32` cannot be made by summing an iterator over elements of type `&()`
--> $DIR/invalid-iterator-chain.rs:31:20
|
LL | println!("{}", vec![(), ()].iter().sum::<i32>());
| ^^^^^^^^^^^^^^^^^^^ --- required by a bound introduced by this call
| |
| value of type `i32` cannot be made by summing a `std::iter::Iterator<Item=&()>`
|
= help: the trait `Sum<&()>` is not implemented for `i32`
= 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:31:33
|
LL | println!("{}", vec![(), ()].iter().sum::<i32>());
| ------------ ^^^^^^ `Iterator::Item` is `&()` here
| |
| this expression has type `Vec<()>`
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 `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:40:23
|
LL | let g: Vec<i32> = f.collect();
| ^ ------- required by a bound introduced by this call
| |
| value of type `Vec<i32>` cannot be built from `std::iter::Iterator<Item=()>`
|
= 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:36:15
|
LL | let a = vec![0];
| ------- this expression has type `Vec<{integer}>`
LL | let b = a.into_iter();
| ----------- `Iterator::Item` is `{integer}` here
LL | let c = b.map(|x| x + 1);
| -------------- `Iterator::Item` remains `{integer}` here
LL | let d = c.filter(|x| *x > 10 );
| -------------------- `Iterator::Item` remains `{integer}` here
LL | let e = d.map(|x| {
| _______________^
LL | | x + 1;
LL | | });
| |______^ `Iterator::Item` changed to `()` here
LL | let f = e.filter(|_| false);
| ----------------- `Iterator::Item` remains `()` here
note: required by a bound in `collect`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
LL | fn collect<B: FromIterator<Self::Item>>(self) -> B
| ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Iterator::collect`

error: aborting due to 6 previous errors

For more information about this error, try `rustc --explain E0277`.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ LL | foo(panic!())
| --- ^^^^^^^^
| | |
| | the trait `T` is not implemented for `()`
| | this tail expression is of type `_`
| | this tail expression is of type `()`
| required by a bound introduced by this call
|
note: required by a bound in `foo`
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/on-unimplemented/sum.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ LL | vec![(), ()].iter().sum::<i32>();
= 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/sum.rs:4:18
|
LL | vec![(), ()].iter().sum::<i32>();
| ------------ ^^^^^^ `Iterator::Item` is `&()` here
| |
| this expression has type `Vec<()>`
note: required by a bound in `std::iter::Iterator::sum`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
Expand All @@ -28,6 +35,13 @@ LL | vec![(), ()].iter().product::<i32>();
= help: the following other types implement trait `Product<A>`:
<i32 as Product<&'a i32>>
<i32 as Product>
note: the method call chain might not have had the expected associated types
--> $DIR/sum.rs:7:18
|
LL | vec![(), ()].iter().product::<i32>();
| ------------ ^^^^^^ `Iterator::Item` is `&()` here
| |
| this expression has type `Vec<()>`
note: required by a bound in `std::iter::Iterator::product`
--> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
|
Expand Down