Skip to content

Bogus suggestion on I::Item vs &I::Item mismatch #112104

Open
@bugaevc

Description

@bugaevc

Code

fn foo<I: Iterator>(mut iter: I, value: &I::Item) where I::Item: Eq + Debug {
    assert_eq!(iter.next(), Some(value));
}

Current output

error[E0308]: mismatched types
 --> src/lib.rs:4:5
  |
4 |     assert_eq!(iter.next(), Some(value));
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Option<<I as Iterator>::Item>`, found `Option<&<I as Iterator>::Item>`
  |
  = note: expected enum `Option<<I as Iterator>::Item>`
             found enum `Option<&<I as Iterator>::Item>`
  = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider constraining the associated type `<I as Iterator>::Item` to `&<I as Iterator>::Item`
  |
3 | fn foo<I: Iterator<Item = &<I as Iterator>::Item>>(mut iter: I, value: &I::Item) where I::Item: Eq + Debug {
  |                   +++++++++++++++++++++++++++++++

For more information about this error, try `rustc --explain E0308`.

Desired output

error: cannot compare Option<I::Item> to Option<&I::Item>
 --> src/lib.rs:4:5
  |
4 |     assert_eq!(iter.next(), Some(value));

help: consider using `.as_ref()` to convert `Option<I::Item>` to `Option<&I::Item>`:
  |
4 |     assert_eq!(iter.next().as_ref(), Some(value));
  |                           +++++++++

Rationale and extra context

Item = &Item obviously wouldn't work, the compiler should not suggest that. The proper fix here is to convert the first Option<I::Item> to an Option<&I::Item> by calling .as_ref() on it.

Other cases

No response

Anything else?

This is reduced from a real example where I was trying to check that the iterator emits the expected series of items:

fn assert_collect<I: IntoIterator>(iter: I, expected_items: &[I::Item]) where I::Item: Eq + Debug {
    let mut iter = iter.into_iter();
    for item in expected_items {
        assert_eq!(iter.next(), Some(item));
    }
    assert_eq!(iter.next(), None);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.S-has-mcveStatus: A Minimal Complete and Verifiable Example has been found for this issueT-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