My view about this message is that it should reflect the fact that the type T is potentially used for types that doesn't implement the Debug protocol, rather then stating that it is not implemented, which in my case is just not true.
I am very much interested in your opinions. Please treat me as a rust beginner and sorry for the potentially silly question. What do you think?
Well, the key insight here is that T is not f32 or i32; it's a distinct concept. I mean, sure, it has f32 and i32 substituted in its place, but so far as the compiler is concerned, T is its own thing within that code.
To put it another way: the only things the compiler is allowed to assume about T are the things you've specifically told it.
The message could probably be improved by checking for generic parameters and noting that you maybe need to constrain them. Rust has similar suggestions in a few places already.
I see, thank you very much for the reply. Once I understood, I liked this way of treating generics, actually a lot more than it is in C++ templates.
Since this is my first few lines in Rust it took quite some time to understand what was wrong. I think it is more helpful for the beginners like me to improve the error message.
So I like how Rust works as much I understood, just the error message has raised the bar to jump in.
I'm not sure I would call the error misleading. Is there a compiler out there that looks at the actually implemented instances of a generic to infer what traits (interfaces) it has?
Well there is JavaScript I guess, but that's an interpreted language so the methods an object has isn't know until it actually runs.....
And if this generic is put into a crate (library) that would be impossible because it wouldn't know until it tried linking with the external code.
I know in Java I can't create a generic and call random functions on it, I have to tell Java what interface/class the generic implements or extends before I can call functions on it. But maybe that is a bad example because Java is a pretty old language now. Not sure about the some of the newer non interpreted languages....
I found it misleading (may be because of my C++ background) because I read it like I need to implement something additional for T, rather then constraining the T in the generic trait. May be one more sentence clarifying this would be helpful for the poor C++ folks.
I started to realize that others, coming from non-C++ background understanding the message easier than I did.
The rustc_on_unimplemented message for fmt::Debug is confusing:
note: `T` cannot be formatted using `:?`; if it is defined in your crate, add `#[derive(Debug)]` or manually implement it
Maybe we should not display the rustc_on_unimplemented message when the type is not implemented because of type parameters (e.g. replace the type parameters with variables and check whether the evaluation is ambig?).
example.rs:19:33: 19:34 error: the trait `core::fmt::Debug` is not implemented for the type `T` [E0277]
example.rs:19 println!("trait: {:?}", i);
^
<std macros>:2:25: 2:56 note: in this expansion of format_args!
<std macros>:3:1: 3:54 note: in this expansion of print! (defined in <std macros>)
example.rs:19:9: 19:36 note: in this expansion of println! (defined in <std macros>)
example.rs:19:33: 19:34 help: run `rustc --explain E0277` to see a detailed explanation
example.rs:19:33: 19:34 help: consider adding a `where T : core::fmt::Debug` bound
example.rs:19:33: 19:34 note: required by `core::fmt::Debug::fmt`
I see. Thank you. It is better. May be I am wrong on nit picking on this part, but to be honest this was more confusing for me:
This is telling me that Debug is not implemented, while in practice, the compiler doesn't care about what is implemented, it cares about what the constraint was for T. This may be obvious for everyone else, but for me this is telling me that I need to do something with T and thus i, rather than adding a constraint trait in the generics declaration.