Repository navigation
Description
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
minfound for typeTin the current scope
note: the methodminexists 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 itemmin, 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
minfound for typeTin the current scope
note: the methodminexists 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 itemmin, perhaps you need toimplementdeclare one of them forT:
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}: Minimumis not satisfied
label: the traitMinimumis not implemented for{integer}
note: required byvec_min
which is straightforward enough.
Activity
Mark-Simulacrum commentedon Jun 20, 2017
Today, we suggest that the method exists, but we somehow fail to see that it exists on Minimum in the first note and then latter note it in the second note.
louy2 commentedon Jun 21, 2017
It still doesn't help a lot IMO... since the problem is the bound isn't declared in the signature, and nothing regarding declaration is mentioned.
maybe change to
kornelski commentedon Oct 3, 2017
I think that can be easily fixed by checking if
unsatisfied_predicatesis not empty and using a different message in that case https://github.com/rust-lang/rust/blob/master/src/librustc_typeck/check/method/suggest.rs#L175Do you have suggestion how the error should look like? Does that sound ok?
louy2 commentedon Oct 4, 2017
@pornel
I don't think your error message communicates much more than the current one. I also think the error message is already straightforward enough.
From my perspective, I think the problem is one of asymmetry in the help section. It mentioned "items from traits can only be used if the trait is implemented and in scope", but then went on to only suggest "perhaps you need to implement one of them". Excuse me for being insistent on this, but I believe the best way is to remind that to bring function into scope the trait bound needs to be declared as well as implemented.
louy2 commentedon Oct 4, 2017
LOL this is actually a duplicate of #21673 . There's even a FIXME note in the source.
kornelski commentedon Oct 4, 2017
@louy2 I think we're talking about different cases (which may be another reason to split or reword the message). For methods the message says "method not found", but adds a note saying "the method exists", which I really don't like, because it's very easy to miss the nuance and interpret the message as nonsense "the method does not exist" "but it exists".
I've explained more here:
https://internals.rust-lang.org/t/multiple-variants-of-the-same-erorr-message/6002
estebank commentedon Jul 17, 2019
With #62772 the output will be:
Rollup merge of rust-lang#62772 - estebank:trait-bound, r=matthewjasper
Rollup merge of rust-lang#62772 - estebank:trait-bound, r=matthewjasper
Rollup merge of rust-lang#62772 - estebank:trait-bound, r=matthewjasper