Rust: Invalid error while using Debug as trait:

Created on 10 Sep 2020  ·  11Comments  ·  Source: rust-lang/rust

I tried this a code that did not implemented the Debug trait, and it failed correctly:

/data/Projects/adventofcode on  master! ⌚ 12:09:49
$ cargo run --bin advent_of_code_06 -- --filename src/bin/input_06.txt
   Compiling adventofcode v0.1.0 (/data/Projects/adventofcode)
error[E0277]: `T` doesn't implement `Debug`
  --> src/bin/advent_of_code_06.rs:48:33
   |
48 |                 print!("{:?},", self.m[ (i * self.len) + e]);
   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
   |
   = note: required by `std::fmt::Debug::fmt`
   = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting this bound
   |
43 | impl<T: Sized + PartialEq + Debug> Matrix<T> {
   |                           ^^^^^^^

error: aborting due to previous error

Looking at the line 43 of my output, the one that asks me to add the + Debug to the line:

error[E0404]: expected trait, found derive macro `Debug`
  --> src/bin/advent_of_code_06.rs:43:29
   |
43 | impl<T: Sized + PartialEq + Debug> Matrix<T> {
   |                             ^^^^^ not a trait
   |

The compiler should tell me the correct Trait missing, and not one that will not work during compilation.
I solved this by setting the trait to be std::fmt::Debug instead of Debug

rustc --version --verbose:

$ rustc --version --verbose
rustc 1.48.0-nightly (5099914a1 2020-09-08)
binary: rustc
commit-hash: 5099914a16a215794ad243df0cc7a05d91d168e0
commit-date: 2020-09-08
host: x86_64-unknown-linux-gnu
release: 1.48.0-nightly
LLVM version: 11.0
A-diagnostics A-suggestion-diagnostics C-bug D-invalid-suggestion

Most helpful comment

I did, but tested wrongly - I misunderstood the lambda, now it's working (half) as I want:

help: consider restricting type parameter `T`
  |
7 | impl<T: std::fmt::Debug> Test<T> {
  |       ^^^^^^^^^^^^^^^^^

That fixes half of my issues, the other I just tougth about: "What if the user has imported the std::fmt::Debug to the current scope? then it should only print Debug - as it was, so the debug output should be semantically correct depending on my code.

I think now I need to fix the testcases with the new string, and open the MR, while I also study the source to understand how to change this patch later to the behavior I described above.

[also, thanks for your time, I know it would be much faster if you did it, but I really wanted to learn and submit something to rust]

All 11 comments

I think this suggestion in the diagnostic should have helped:

help: consider importing one of these items instead
  |
1 | use core::fmt::Debug;

Importing core::fmt::Debug solves the error.

This is fallout from the unique ident shortening change. I feel that the existing import suggestion is enough for now as the prevalent style is to import traits and use the local name, which is the end result of following the current suggestions. That being said, I wouldn't be against someone changing this suggestion to use the fully qualified path as we used to (and would be a small patch).

@estebank I have never contributed to rust before but I would like to try, I do have rust master compilled locally, can you point me to the right way?

@LeSeulArtichaut putting yourself in the shoes of a newcommer on rust language, the current behavior is frustrating as the first help message triggers a second one in a subsequent build, even if the second one does indeed show you what should you do to fix.

If you want to hack on this (❤️), the rustc-dev-guide has a chapter on diagnostics which might come in handy.

This error is emitted here: https://github.com/rust-lang/rust/blob/d2454643e137bde519786ee9e650c455d7ad6f34/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs#L309-L314

The PR that changed the behavior was https://github.com/rust-lang/rust/pull/73996, which introduced a function with_no_trimmed_paths that would let you easily change these two calls here to the fully qualified path:

https://github.com/rust-lang/rust/blob/d2454643e137bde519786ee9e650c455d7ad6f34/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs#L297-L305

@estebank @LeSeulArtichaut thanks, I'm compilling current master to try. :+1:

I almost made it. :)

error[E0277]: `T` doesn't implement `Debug`
 --> main.rs:9:25
  |
9 |         print!("{:?},", self.m);
  |                         ^^^^^^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug`
  |
  = note: required by `std::fmt::Debug::fmt`
  = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider restricting type parameter `T`
  |
7 | impl<T: <T as std::fmt::Debug>> Test<T> {
  |       ^^^^^^^^^^^^^^^^^^^^^^^^

of course it's easy to see the error on my line 7, as it should be 7 | impl<T: std::fmt::Debug> Test<T> {

I tried getting all of the output on the terminal during compilation time, to find the correct one:
on file rust/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs, line 437:

println!(" Types: {:?}, {:?}", trait_ref.skip_binder(), trait_ref.skip_binder().to_string())
output: <T as std::fmt::Debug>, "<T as Debug>"

so aparently I need to print_only_trait_path() on the string that goes to the Debug formatter, not the default formatter.
Then I got lost. Any subsequent hints?

Did you try using {} instead of {:?} for with_no_trimmed_paths(|| trait_ref.print_only_trait_path())? That _should_ print out std::fmt::Debug.

I did, but tested wrongly - I misunderstood the lambda, now it's working (half) as I want:

help: consider restricting type parameter `T`
  |
7 | impl<T: std::fmt::Debug> Test<T> {
  |       ^^^^^^^^^^^^^^^^^

That fixes half of my issues, the other I just tougth about: "What if the user has imported the std::fmt::Debug to the current scope? then it should only print Debug - as it was, so the debug output should be semantically correct depending on my code.

I think now I need to fix the testcases with the new string, and open the MR, while I also study the source to understand how to change this patch later to the behavior I described above.

[also, thanks for your time, I know it would be much faster if you did it, but I really wanted to learn and submit something to rust]

Hm, no. my fix is wrong, as the tests that have use std::fmt::Debug; will now fail with "ERROR: Does not implement std::fmt::Debug` instead of Debug.

So, last question before I probably manage to fix this properly: how can I test if the "trait_ref" is fully defined / imported to the namespace, before choosing to display "std::fmt::Debug" or just "Debug" on the error output?

The behavior you want is not possible at this point. You would need to look at the locally available names for the given DefId, but this is not something that the compiler is currently geared towards. There's an open ticket to do exactly that and things should just work once the machinery is put in place.

Was this page helpful?
0 / 5 - 0 ratings