Skip to content

"is not an iterator" diagnostic through blanket implementation, when the type is actually an iterator but is missing a marker #127511

Closed
@progval

Description

@progval

Code

(inspired by rayon's ParallelBridge)

pub trait ParallelBridge: Sized {
    // Required method
    fn par_bridge(self) -> ();
}

impl<T: Iterator + Send> ParallelBridge for T
where
    T::Item: Send,
{
    fn par_bridge(self) -> () {
        unimplemented!("par_bridge");
    }
}


fn f(it: impl Iterator<Item=u64>) {
    it.map(|i| i+1).par_bridge()
}

fn main() -> std::io::Result<()> {
    let (_tx, rx) = std::sync::mpsc::sync_channel(1000);
    f(rx.iter());

    Ok(())
}

playground

Current output

Compiling playground v0.0.1 (/playground)
error[E0599]: no method named `par_bridge` found for struct `Map<impl Iterator<Item = u64>, {closure@src/main.rs:17:12: 17:15}>` in the current scope
  --> src/main.rs:17:21
   |
17 |     it.map(|i| i+1).par_bridge()
   |                     ^^^^^^^^^^ `Map<impl Iterator<Item = u64>, {closure@src/main.rs:17:12: 17:15}>` is not an iterator
   |
help: call `.into_iter()` first
   |
17 |     it.map(|i| i+1).into_iter().par_bridge()
   |                     ++++++++++++

For more information about this error, try `rustc --explain E0599`.
error: could not compile `playground` (bin "playground") due to 1 previous error

Desired output

The same error there is when removing the .map()

   Compiling playground v0.0.1 (/playground)
error[E0599]: no method named `par_bridge` found for type parameter `impl Iterator<Item = u64>` in the current scope
  --> src/main.rs:17:8
   |
16 | fn f(it: impl Iterator<Item=u64>) {
   |          ----------------------- method `par_bridge` not found for this type parameter
17 |     it.map(|i| i+1).par_bridge()
   |        ^^^^^^^^^^ method cannot be called on `impl Iterator<Item = u64>` due to unsatisfied trait bounds
   |
   = help: items from traits can only be used if the type parameter is bounded by the trait
help: the following trait defines an item `par_bridge`, perhaps you need to restrict type parameter `impl Iterator<Item = u64>` with it:
   |
16 | fn f(it: impl Iterator<Item=u64> + ParallelBridge) {
   |                                  ++++++++++++++++

For more information about this error, try `rustc --explain E0599`.
error: could not compile `playground` (bin "playground") due to 1 previous error

Rationale and extra context

The error indicated the type does not implement Iterator, even though it does and Send is the one that is missing.

Other cases

No response

Rust Version

rustc 1.79.0

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions