How can I get a list of the "and 17 others" types in this compilation error?

Occasionally I get into a situation where a trait is implemented for a lot of types and the compiler won't show them all to me. Example is below. Instead, it just tells me how many it has refused to print.

Is there a way to get the full list? Ideally, using a flag on "cargo check", but I'll settle for any option (LSP based, hacking the code using some trick, etc.).

error[E0277]: the trait bound `MaybeMissing<std::string::String>: Reconcile` is not satisfied
   --> src/main.rs:3:19
    |
3   | #[derive(Hydrate, Reconcile)]
    |                   ^^^^^^^^^ the trait `Reconcile` is not implemented for `MaybeMissing<std::string::String>`, which is required by `&MaybeMissing<std::string::String>: Reconcile`
4   | struct S {
5   |     s: MaybeMissing<String>,
    |     - required by a bound introduced by this call
    |
    = help: the following other types implement trait `Reconcile`:
              bool
              i8
              i16
              i32
              i64
              u8
              u16
              u32
            and 17 others
    = note: required for `&MaybeMissing<std::string::String>` to implement `Reconcile`
note: required by a bound in `autosurgeon::reconcile::MapReconciler::put`
   --> /home/matt/.cargo/registry/src/index.crates.io-6f17d22bba15001f/autosurgeon-0.8.3/src/reconcile.rs:114:15
    |
114 |     fn put<R: Reconcile, P: AsRef<str>>(&mut self, prop: P, value: R) -> Result<(), Self::Error>;
    |               ^^^^^^^^^ required by this bound in `MapReconciler::put`

Well, there is a list here:

and

Maybe --message-format json is enough.

It is not.

There is curently no way to change the output of rustc: report_similar_impl_candidates

2 Likes

This does not cover implementations in other crates unless you build the docs yourself. But building yourself is not possible if your code fails to compile.

Sorry but I needed a code example, so here: (playground)

trait Reconcile {
    fn reconcile(&self);
}

// Implementing the trait for some types
impl Reconcile for bool {
    fn reconcile(&self) {
        println!("Reconciling bool");
    }
}

impl Reconcile for i8 {
    fn reconcile(&self) {
        println!("Reconciling i8");
    }
}

impl Reconcile for i16 {
    fn reconcile(&self) {
        println!("Reconciling i16");
    }
}

impl Reconcile for i32 {
    fn reconcile(&self) {
        println!("Reconciling i32");
    }
}

impl Reconcile for i64 {
    fn reconcile(&self) {
        println!("Reconciling i64");
    }
}

impl Reconcile for u8 {
    fn reconcile(&self) {
        println!("Reconciling u8");
    }
}

impl Reconcile for u16 {
    fn reconcile(&self) {
        println!("Reconciling u16");
    }
}

impl Reconcile for u32 {
    fn reconcile(&self) {
        println!("Reconciling u32");
    }
}

impl Reconcile for i128 {
    fn reconcile(&self) {
        println!("Reconciling u32");
    }
}

impl Reconcile for u128 {
    fn reconcile(&self) {
        println!("Reconciling u32");
    }
}

fn process<T: Reconcile>(item: T) {
    item.reconcile();
}

fn main() {
    let value = String::from("This will cause an error");
    process(value); // This line will cause a compilation error
}

output:

⣿
Errors

Exited with status 101

Standard Error

   Compiling playground v0.0.1 (/playground)
error[E0277]: the trait bound `String: Reconcile` is not satisfied
  --> src/main.rs:72:13
   |
72 |     process(value); // This line will cause a compilation error
   |     ------- ^^^^^ the trait `Reconcile` is not implemented for `String`
   |     |
   |     required by a bound introduced by this call
   |
   = help: the following other types implement trait `Reconcile`:
             bool
             i128
             i16
             i32
             i64
             i8
             u128
             u16
           and 2 others
note: required by a bound in `process`
  --> src/main.rs:66:15
   |
66 | fn process<T: Reconcile>(item: T) {
   |               ^^^^^^^^^ required by this bound in `process`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` (bin "playground") due to 1 previous error

local rustc patch, because of course:

Index: /var/tmp/portage/dev-lang/rust-1.76.0-r1/work/rustc-1.76.0-src/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
===================================================================
--- .orig/var/tmp/portage/dev-lang/rust-1.76.0-r1/work/rustc-1.76.0-src/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ rustc-1.76.0-src/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -2096,16 +2096,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for Ty
                 })
                 .collect();
 
-            let end = if candidates.len() <= 9 { candidates.len() } else { 8 };
             err.help(format!(
-                "the following {other}types implement trait `{}`:{}{}",
+                "the following {other}types implement trait `{}`:{}",
                 trait_ref.print_trait_sugared(),
-                candidates[..end].join(""),
-                if candidates.len() > 9 {
-                    format!("\nand {} others", candidates.len() - 8)
-                } else {
-                    String::new()
-                }
+                candidates.join(""),
             ));
             true
         };

output:

   Compiling and_17_others v0.1.0 (/home/user/sandbox/rust/05_sandbox/error/and_17_others)
error[E0277]: the trait bound `String: Reconcile` is not satisfied
  --> /home/user/sandbox/rust/05_sandbox/error/and_17_others/src/main.rs:72:13
   |
72 |     process(value); // This line will cause a compilation error
   |     ------- ^^^^^ the trait `Reconcile` is not implemented for `String`
   |     |
   |     required by a bound introduced by this call
   |
   = help: the following other types implement trait `Reconcile`:
             bool
             i8
             i16
             i32
             i64
             i128
             u8
             u16
             u32
             u128
note: required by a bound in `process`
  --> /home/user/sandbox/rust/05_sandbox/error/and_17_others/src/main.rs:66:15
   |
66 | fn process<T: Reconcile>(item: T) {
   |               ^^^^^^^^^ required by this bound in `process`

For more information about this error, try `rustc --explain E0277`.
error: could not compile `and_17_others` (bin "and_17_others") due to 1 previous error

ah, much better, thanks Bruecki for pointing to the implementation!

Thanks, so it seems:

  1. The most pragmatic option to finding which types implement which traits is often to go check the docs.
  2. To get better output from the compiler, hack it yourself. :slight_smile: This is a half joke. I know in clang there are a few cases where it refuses to spam long lists of details in its errors, but you can opt in to more with a command line flag. Rust lacks a flag for this case, but it could probably be added.
1 Like

When encountering things like this, I'd encourage you to file a ticket in the issue tracker. Took the liberty to do so for you: Expand list of trait implementers in E0277 when calling `rustc` with `--verbose` · Issue #125984 · rust-lang/rust · GitHub

In my experience I've never needed the full list of implementers when encountering an E0277 and there were more than a handful, but not providing a way to show the full list is an oversight.

8 Likes

Thank you. When new to a project, it is often difficult to know how or where to report bugs and feature requests. Your example was very helpful!

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.