E0599: confusing error and unhelpful suggestion on unsatisfied associated type bound in trait impl
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
Code
use std::iter::Sum;
trait SumIter<T> {
fn sum_iter(self) -> T;
}
impl<A> SumIter<A::Item> for A
where
A: IntoIterator<Item: Sum>,
{
fn sum_iter(self) -> A::Item {
self.into_iter().sum::<A::Item>()
}
}
fn sum_vec<T>(a: Vec<T>) -> T {
a.sum_iter()
}
Current output
error[E0599]: no method named `sum_iter` found for struct `Vec<T>` in the current scope
--> src/lib.rs:16:7
|
16 | a.sum_iter()
| ^^^^^^^^ `Vec<T>` is not an iterator
|
help: call `.into_iter()` first
|
16 | a.into_iter().sum_iter()
| ++++++++++++
Desired output
error[E0599]: the method `sum_iter` exists for struct `Vec<T>`, but its trait bounds were not satisfied
--> src/lib.rs:18:7
|
18 | a.sum_iter()
| ^^^^^^^^
[...]
| doesn't satisfy `Vec<T>: SumIter<Vec<T>>` or `Vec<T>: IntoIterator<Item: Sum>` because `T: Sum` is not satisfied
|
7 | impl<A> SumIter<A> for A
| ^ ---------- -
| |
| unsatisfied trait bound introduced here
8 | where
9 | A: IntoIterator<Item: Sum>,
| ^^^ required by this bound
Rationale and extra context
The actual issue is that T doesn't implement Sum, but the Sum trait is not mentioned anywhere in the error output. The claim that Vec<T> is not iterable is misleading and confusing, and the suggestion to add .into_iter() is unhelpful.
Actually following the suggestion just results in the same error again:
error[E0599]: no method named `sum_iter` found for struct `std::vec::IntoIter<T>` in the current scope
--> src/lib.rs:17:19
|
17 | a.into_iter().sum_iter()
| ^^^^^^^^ `std::vec::IntoIter<T>` is not an iterator
|
help: call `.into_iter()` first
|
17 | a.into_iter().into_iter().sum_iter()
| ++++++++++++
Other cases
// introducing an additional type parameter T
// for the item type and specifying the bound on T
// instead of IntoIterator::Item results in a different
// error, but the error still doesn't mention Sum
use std::iter::Sum;
trait SumIter<T> {
fn sum_iter(self) -> T;
}
impl<A, T> SumIter<A::Item> for A
where
A: IntoIterator<Item = T>,
T: Sum,
{
fn sum_iter(self) -> A::Item {
self.into_iter().sum::<A::Item>()
}
}
fn sum_vec<T>(a: Vec<T>) -> T {
a.sum_iter()
}
// ============================
error[E0599]: the method `sum_iter` exists for struct `Vec<T>`, but its trait bounds were not satisfied
--> src/lib.rs:18:7
|
18 | a.sum_iter()
| ^^^^^^^^
|
note: the following trait bounds were not satisfied:
`<[T] as IntoIterator>::Item = _`
`[T]: IntoIterator`
`[T]: Sized`
--> src/lib.rs:7:6
|
7 | impl<A, T> SumIter<A::Item> for A
| ^ ---------------- -
| |
| unsatisfied trait bound introduced here
8 | where
9 | A: IntoIterator<Item = T>,
| ^^^^^^^^^^^^^^^^^^^^^^
| | |
| | unsatisfied trait bound introduced here
| unsatisfied trait bound introduced here
= note: the following trait bounds were not satisfied:
`<[T] as IntoIterator>::Item = _`
which is required by `[T]: SumIter<_>`
= help: items from traits can only be used if the trait is implemented and in scope
note: `SumIter` defines an item `sum_iter`, perhaps you need to implement it
--> src/lib.rs:3:1
|
3 | trait SumIter<T> {
| ^^^^^^^^^^^^^^^^
help: consider relaxing the type parameter's implicit `Sized` bound
|
7 | impl<A: ?Sized, T> SumIter<A::Item> for A
| ++++++++
Rust Version
> rustc --version --verbose
rustc 1.83.0 (90b35a623 2024-11-26)
binary: rustc
commit-hash: 90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf
commit-date: 2024-11-26
host: x86_64-unknown-linux-gnu
release: 1.83.0
LLVM version: 19.1.1
Anything else?
The same scenario but using bounds on a function instead of a trait impl results in the correct error message and a helpful suggestion:
fn sum_iter<I>(i: I) -> I::Item
where
I: IntoIterator<Item: Sum>,
{
i.into_iter().sum::<I::Item>()
}
fn sum_vec<T>(a: Vec<T>) -> T {
sum_iter(a)
}
error[E0277]: a value of type `T` cannot be made by summing an iterator over elements of type `T`
--> src/lib.rs:18:14
|
18 | sum_iter(a)
| -------- ^ value of type `T` cannot be made by summing a `std::iter::Iterator<Item=T>`
| |
| required by a bound introduced by this call
|
note: required by a bound in `sum_iter`
--> src/lib.rs:23:27
|
21 | fn sum_iter<I>(i: I) -> I::Item
| -------- required by a bound in this function
22 | where
23 | I: IntoIterator<Item: Sum>,
| ^^^ required by this bound in `sum_iter`
help: consider restricting type parameter `T`
|
17 | fn sum_vec<T: std::iter::Sum>(a: Vec<T>) -> T {
| ++++++++++++++++
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the diagnostic from the src/lib.rs examples with rustc 1.83.0, then compare the trait-impl case with the function-bound case that already reports the Sum bound correctly. Trace the E0599 method-lookup and trait-bound diagnostic path; done means the impl case identifies the unsatisfied Sum bound and no longer suggests an invalid extra into_iter call.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 42/100