Skip to content

Confusing Error Message On Not Specifying Trait Bound In Generic Function Signature #41030

Closed
@louy2

Description

@louy2

I am working through this Rust-101 tutorial and is faced with such a challenge:

There is a crucial difference to templates in C++: We actually have to declare which traits we want the type to satisfy. If we left away the Minimum, Rust would have complained that we cannot call min. Just try it!

So I tried it. Rust complained, but in a pretty confusing way:

no method named min found for type T in the current scope
note: the method min exists but the following trait bounds were not satisfied: T : std::iter::Iterator
help: items from traits can only be used if the trait is implemented and in scope; the following traits define an item min, perhaps you need to implement one of them:
help: candidate #1: part02::Minimum
help: candidate #2: part07::Minimum
help: candidate #3: std::iter::Iterator

The minimal code that produces the error message is

// main.rs
pub enum SomethingOrNothing<T>  {
    Something(T),
    Nothing,
}
pub use self::SomethingOrNothing::*;

pub trait Minimum : Copy {
    fn min(self, b: Self) -> Self;
}

pub fn vec_min<T/*: Minimum*/>(v: Vec<T>) -> SomethingOrNothing<T> {
    let mut min = Nothing;
    for e in v {
        min = Something(match min {
            Nothing => e,
            // Here, we can now call the `min` function of the trait.
            Something(n) => {
                e.min(n)
            }
        });
    }
    min
}

impl Minimum for i32 {
    fn min(self, b: Self) -> Self {
        if self < b { self } else { b }
    }
}

fn main() {
    let v = vec![18,5,7,3,9,27];
    let min = vec_min(v);
}

The error message tells me that I need to implement a trait. Since I have already implemented it, I would be confused by the error message, and misled by it from the actual reason, failure to declare it in the signature. I think it would be better if the message is changed to

no method named min found for type T in the current scope
note: the method min exists but the following trait bounds were not satisfied: T : std::iter::Iterator
help: items from traits can only be used if the trait is implemented and in scope; the following traits define an item min, perhaps you need to implement declare one of them for T:
help: candidate #1: part02::Minimum
help: candidate #2: part07::Minimum
help: candidate #3: std::iter::Iterator

On the other hand, if I actually drop the block impl Minimum for i32, but declare Minimum in the signature, the error message is

E0277: the trait bound {integer}: Minimum is not satisfied
label: the trait Minimum is not implemented for {integer}
note: required by vec_min

which is straightforward enough.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsC-enhancementCategory: An issue proposing an enhancement or a PR with one.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions