Misleading suggestion for missing trait bounds
This is a simplified version of https://users.rust-lang.org/t/solved-iterator-filter-and-zip-in-place/9809/4
trait Foo {
fn foo(self) -> Self;
}
impl<I, T, U> Foo for I
where I: Iterator<Item = (T, U)>
{
fn foo(self) -> Self {
self
}
}
fn main() {
let v = vec![(1, 'a'), (2, 'b'), (3, 'c')];
for x in v.iter().foo() {
println!("{:?}", x);
}
}
The error is:
error: no method named `foo` found for type `std::slice::Iter<'_, ({integer}, char)>` in the current scope
--> <anon>:15:23
|
15 | for x in v.iter().foo() {
| ^^^
|
= note: the method `foo` exists but the following trait bounds were not satisfied: `&std::slice::Iter<'_, ({integer}, char)> : std::iter::Iterator`
= help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `foo`, perhaps you need to implement it:
= help: candidate #1: `Foo`
The note: chose to report missing &Iter: Iterator, which is true, but it's not best thing it could have noted. I guess it's looking at &Iter because of some auto-ref in the method call. But if you force it to use Iter directly with UFCS, like Foo::foo(v.iter()), the note is more useful.
error[E0271]: type mismatch resolving `<std::slice::Iter<'_, ({integer}, char)> as std::iter::Iterator>::Item == (_, _)`
--> <anon>:15:14
|
15 | for x in Foo::foo(v.iter()) {
| ^^^^^^^^ expected reference, found tuple
|
= note: expected type `&({integer}, char)`
found type `(_, _)`
= note: required because of the requirements on the impl of `Foo` for `std::slice::Iter<'_, ({integer}, char)>`
= note: required by `Foo::foo`
So we do have an Iterator, just the wrong Item.
This is a simplified version of https://users.rust-lang.org/t/solved-iterator-filter-and-zip-in-place/9809/4
trait Foo { fn foo(self) -> Self; } impl<I, T, U> Foo for I where I: Iterator<Item = (T, U)> { fn foo(self) -> Self { self } } fn main() { let v = vec![(1, 'a'), (2, 'b'), (3, 'c')]; for x in v.iter().foo() { println!("{:?}", x); } }error: no method named `foo` found for type `std::slice::Iter<'_, ({integer}, char)>` in the current scope --> <anon>:15:23 | 15 | for x in v.iter().foo() { | ^^^ | = note: the method `foo` exists but the following trait bounds were not satisfied: `&std::slice::Iter<'_, ({integer}, char)> : std::iter::Iterator` = help: items from traits can only be used if the trait is implemented and in scope; the following trait defines an item `foo`, perhaps you need to implement it: = help: candidate #1: `Foo`The
note:chose to report missing&Iter: Iterator, which is true, but it's not best thing it could have noted. I guess it's looking at&Iterbecause of some auto-ref in the method call. But if you force it to useIterdirectly with UFCS, likeFoo::foo(v.iter()), the note is more useful.error[E0271]: type mismatch resolving `<std::slice::Iter<'_, ({integer}, char)> as std::iter::Iterator>::Item == (_, _)` --> <anon>:15:14 | 15 | for x in Foo::foo(v.iter()) { | ^^^^^^^^ expected reference, found tuple | = note: expected type `&({integer}, char)` found type `(_, _)` = note: required because of the requirements on the impl of `Foo` for `std::slice::Iter<'_, ({integer}, char)>` = note: required by `Foo::foo`So we do have an
Iterator, just the wrongItem.Esteban Kuber at 2019-04-29 00:35:10
Current output:
error[E0599]: no method named `foo` found for type `std::slice::Iter<'_, ({integer}, char)>` in the current scope --> src/main.rs:15:23 | 15 | for x in v.iter().foo() { | ^^^ method not found in `std::slice::Iter<'_, ({integer}, char)>` | = note: the method `foo` exists but the following trait bounds were not satisfied: `&mut std::slice::Iter<'_, ({integer}, char)> : Foo` `&std::slice::Iter<'_, ({integer}, char)> : Foo` `std::slice::Iter<'_, ({integer}, char)> : Foo` = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `foo`, perhaps you need to implement it: candidate #1: `Foo`Esteban Kuber at 2019-10-15 18:09:54
Triage: no change.
Esteban Kuber at 2020-02-03 18:49:40
Current output, very little change:
error[E0599]: no method named `foo` found for struct `std::slice::Iter<'_, ({integer}, char)>` in the current scope --> src/main.rs:15:23 | 15 | for x in v.iter().foo() { | ^^^ method not found in `std::slice::Iter<'_, ({integer}, char)>` | = note: the method `foo` exists but the following trait bounds were not satisfied: `<std::slice::Iter<'_, ({integer}, char)> as std::iter::Iterator>::Item = (_, _)` which is required by `std::slice::Iter<'_, ({integer}, char)>: Foo` `<&std::slice::Iter<'_, ({integer}, char)> as std::iter::Iterator>::Item = (_, _)` which is required by `&std::slice::Iter<'_, ({integer}, char)>: Foo` `&std::slice::Iter<'_, ({integer}, char)>: std::iter::Iterator` which is required by `&std::slice::Iter<'_, ({integer}, char)>: Foo` `<&mut std::slice::Iter<'_, ({integer}, char)> as std::iter::Iterator>::Item = (_, _)` which is required by `&mut std::slice::Iter<'_, ({integer}, char)>: Foo`Esteban Kuber at 2020-06-15 19:20:35
Current output:
error[[E0599]](https://doc.rust-lang.org/nightly/error_codes/E0599.html): the method `foo` exists for struct `Iter<'_, ({integer}, char)>`, but its trait bounds were not satisfied --> src/main.rs:15:23 | 15 | for x in v.iter().foo() { | ^^^ method cannot be called on `Iter<'_, ({integer}, char)>` due to unsatisfied trait bounds --> /rustc/8131b9774ebcb6c162fcac71545a13543ec369e7/library/core/src/slice/iter.rs:62:1 | = note: doesn't satisfy `<_ as Iterator>::Item = (_, _)` | = note: doesn't satisfy `std::slice::Iter<'_, ({integer}, char)>: Foo` | note: the following trait bounds were not satisfied: `&std::slice::Iter<'_, ({integer}, char)>: Iterator` `<&mut std::slice::Iter<'_, ({integer}, char)> as Iterator>::Item = (_, _)` `<&std::slice::Iter<'_, ({integer}, char)> as Iterator>::Item = (_, _)` `<std::slice::Iter<'_, ({integer}, char)> as Iterator>::Item = (_, _)` --> src/main.rs:6:14 | 5 | impl<I, T, U> Foo for I | --- - 6 | where I: Iterator<Item = (T, U)> | ^^^^^^^^^^^^^^^^^^^^^^^ | | | | | unsatisfied trait bound introduced here | unsatisfied trait bound introduced hereEsteban Kuber at 2023-08-03 19:18:08
Another case from #36513:
pub trait JoinWithString { fn join(self, separator: &'static str) -> String; } impl<X> JoinWithString for X where X: Iterator<Item = String> { fn join(self, separator: &'static str) -> String { unimplemented!() } } fn main() { let a: Vec<std::path::PathBuf> = Vec::new(); a.iter().map(|x| x.to_str().unwrap()).join(":"); }Esteban Kuber at 2024-02-15 02:29:24
Current output:
error[E0599]: no method named `foo` found for struct `std::slice::Iter<'_, ({integer}, char)>` in the current scope --> src/main.rs:15:23 | 15 | for x in v.iter().foo() { | ^^^ `std::slice::Iter<'_, ({integer}, char)>` is not an iterator | help: call `.into_iter()` first | 15 | for x in v.iter().into_iter().foo() { | ++++++++++++The suggestion is incorrect. It should instead tell the user to replace
iter()withinto_iter().Esteban Kuber at 2024-10-04 23:32:08