Skip to content

Misleading suggestion for missing trait bounds #40375

New issue

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

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

Already on GitHub? # to your account

Open
cuviper opened this issue Mar 8, 2017 · 6 comments
Open

Misleading suggestion for missing trait bounds #40375

cuviper opened this issue Mar 8, 2017 · 6 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@cuviper
Copy link
Member

cuviper commented Mar 8, 2017

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.

@Mark-Simulacrum Mark-Simulacrum added the A-diagnostics Area: Messages for errors, warnings, and lints label May 28, 2017
@Mark-Simulacrum Mark-Simulacrum added the C-enhancement Category: An issue proposing an enhancement or a PR with one. label Jul 26, 2017
@estebank estebank added D-confusing Diagnostics: Confusing error or lint that should be reworked. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 11, 2019
@estebank
Copy link
Contributor

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`

@estebank
Copy link
Contributor

estebank commented Feb 3, 2020

Triage: no change.

@estebank
Copy link
Contributor

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`

@estebank
Copy link
Contributor

estebank commented Aug 3, 2023

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 here

@estebank
Copy link
Contributor

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(":");
}

@estebank
Copy link
Contributor

estebank commented Oct 4, 2024

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() with into_iter().

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-enhancement Category: An issue proposing an enhancement or a PR with one. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-papercut Diagnostics: An error or lint that needs small tweaks. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants