Skip to content

Suggests T: Iterator bound for cmp, when Ord was intended #120186

Closed
@ryanavella

Description

@ryanavella

Code

fn f<T>(a: T, b: T) -> std::cmp::Ordering {
    a.cmp(&b)
}

Current output

error[E0599]: `T` is not an iterator
 --> main.rs:2:7
  |
1 | fn f<T>(a: T, b: T) -> std::cmp::Ordering {
  |      - method `cmp` not found for this type parameter
2 |     a.cmp(&b)
  |       ^^^ `T` is not an iterator
  |
  = note: the following trait bounds were not satisfied:
          `T: Iterator`
          which is required by `&mut T: Iterator`
help: consider restricting the type parameter to satisfy the trait bound
  |
1 | fn f<T>(a: T, b: T) -> std::cmp::Ordering where T: Iterator {
  |                                           +++++++++++++++++

error: aborting due to 1 previous error

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

Desired output

Something that also includes a suggestion of T: Ord. (see further down for examples that do provide this suggestion)

Rationale and extra context

It is my impression that <T as Ord>::cmp is encountered just as often as <T as Iterator>::cmp, if not more often, so I was expecting a suggestion to add a T: Ord bound as well.

Other cases

No response

Rust Version

$ rustc --version --verbose
rustc 1.77.0-nightly (88189a71e 2024-01-19)
binary: rustc
commit-hash: 88189a71e4e4376eea82ac61db6a539612eb200a
commit-date: 2024-01-19
host: x86_64-unknown-freebsd
release: 1.77.0-nightly
LLVM version: 17.0.6

Anything else?

If instead the code is tweaked slightly to the following:

fn f<T>(a: T, b: T) -> std::cmp::Ordering {
    <_>::cmp(&a, &b)
}

It produces a much more helpful diagnostic:

error[E0034]: multiple applicable items in scope
    --> main.rs:2:10
     |
2    |     <_>::cmp(&a, &b)
     |          ^^^ multiple `cmp` found
     |
note: candidate #1 is defined in the trait `Ord`
    --> ~/.rustup/toolchains/nightly-x86_64-unknown-freebsd/lib/rustlib/src/rust/library/core/src/cmp.rs:814:5
     |
814  |     fn cmp(&self, other: &Self) -> Ordering;
     |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: candidate #2 is defined in the trait `Iterator`
    --> ~/.rustup/toolchains/nightly-x86_64-unknown-freebsd/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:3692:5
     |
3692 | /     fn cmp<I>(self, other: I) -> Ordering
3693 | |     where
3694 | |         I: IntoIterator<Item = Self::Item>,
3695 | |         Self::Item: Ord,
3696 | |         Self: Sized,
     | |____________________^
help: use fully-qualified syntax to disambiguate
     |
2    |     Iterator::cmp(&a, &b)
     |     ~~~~~~~~~~
2    |     Ord::cmp(&a, &b)
     |     ~~~~~

error: aborting due to 1 previous error

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

Similarly helpful diagnostics can be seen if we tweak it to <T>::cmp or <&T>::cmp.

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