Skip to content

Compiler error uses re-export name of not-imported crate for a std trait #81973

Open

Description

@davepacheco

I tried this code:

use serde::Deserialize;
use std::error::Error;

pub struct S<ErrorType: Error> {
    p: std::marker::PhantomData<ErrorType>,
}

impl<ErrorType> S<ErrorType> {
    fn f(&self) {
    }
}

I expected to see an error like this:

error[E0277]: the trait bound `ErrorType: std::error::Error` is not satisfied
 --> src/lib.rs:8:17
  |
4 | pub struct S<ErrorType: Error> {
  |                         ----- required by this bound in `S`
...
8 | impl<ErrorType> S<ErrorType> {
  |                 ^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `ErrorType`
  |
help: consider restricting type parameter `ErrorType`
  |
8 | impl<ErrorType: std::error::Error> S<ErrorType> {
  |               ^^^^^^^^^^^^^^^^^^^

Instead, I saw an error like this:

error[E0277]: the trait bound `ErrorType: StdError` is not satisfied
 --> src/lib.rs:8:17
  |
4 | pub struct S<ErrorType: Error> {
  |                         ----- required by this bound in `S`
...
8 | impl<ErrorType> S<ErrorType> {
  |                 ^^^^^^^^^^^^ the trait `StdError` is not implemented for `ErrorType`
  |
help: consider restricting type parameter `ErrorType`
  |
8 | impl<ErrorType: StdError> S<ErrorType> {
  |               ^^^^^^^^^^

Note that the compiler is referring to StdError -- that's not a type in my code nor in scope where the error occurs. I found that if I comment out the use serde::Deserialize; at the top, then the compiler refers to the trait as std::error::Error (as I'd expect). serde does have this in it (under some conditions):

pub use std::error::Error as StdError;

but I haven't pulled that name into scope here.

You can play with this here:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=44c3501773900c0afe548a9a4b871f09

Meta

With the playground link above, the behavior looks the same on stable 1.49, beta 1.50.0-beta.9, and nightly.

Activity

  1. added
    A-diagnosticsArea: Messages for errors, warnings, and lints
    A-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`
    D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    on Feb 10, 2021
  2. estebank commented on Aug 14, 2023

    @estebank
    Contributor

    Current output:

    error[[E0277]](https://doc.rust-lang.org/stable/error_codes/E0277.html): the trait bound `ErrorType: StdError` is not satisfied
     --> src/lib.rs:8:17
      |
    8 | impl<ErrorType> S<ErrorType> {
      |                 ^^^^^^^^^^^^ the trait `StdError` is not implemented for `ErrorType`
      |
    note: required by a bound in `S`
     --> src/lib.rs:4:25
      |
    4 | pub struct S<ErrorType: Error> {
      |                         ^^^^^ required by this bound in `S`
    help: consider restricting type parameter `ErrorType`
      |
    8 | impl<ErrorType: std::error::Error> S<ErrorType> {
      |               +++++++++++++++++++
    
    error[[E0277]](https://doc.rust-lang.org/stable/error_codes/E0277.html): the trait bound `ErrorType: StdError` is not satisfied
     --> src/lib.rs:9:10
      |
    9 |     fn f(&self) {
      |          ^^^^^ the trait `StdError` is not implemented for `ErrorType`
      |
    note: required by a bound in `S`
     --> src/lib.rs:4:25
      |
    4 | pub struct S<ErrorType: Error> {
      |                         ^^^^^ required by this bound in `S`
    help: consider restricting type parameter `ErrorType`
      |
    8 | impl<ErrorType: std::error::Error> S<ErrorType> {
      |               +++++++++++++++++++
    
  3. Marcono1234 commented on Jul 13, 2026

    @Marcono1234
    Contributor

    Current output: ...

    But now the error message refers to both StdError and std::error::Error, possibly causing even more confusion? It seems only the suggested code change has improved to refer to std::error::Error now instead of StdError, but the rest of the error message still refers to StdError.

    The main problems are in my opinion:

    • it is not clear that the name is a re-export
    • it is not clear what original type the re-exported name refers to
      (for StdError maybe you can guess it, but that might not always be possible)
    • it is not clear at all where the re-export came from
      In my case, even when I put the code referring to std::error::Error in lib.rs, it seems to suffice that some nested module somewhere imports Serde types to still cause the error message to refer to it as StdError.

    Is there any chance this issue will be reopened, or should I create a new issue? I only found #17164 but that is about type aliases (and the opposite, where it shows the original type name instead of the alias?).

    Ideally the compiler would only use type names which the user has already used in their code, and not some re-exported names which never occurred so far in the user code. But I am not sure if this is possible.
    So at least some "note" / "hint" section at the end would be useful, something like:

    ...
    note: StdError is a re-export of std::error::Error (defined by crate 'serde')
    note: MyString is a re-export of std::string::String (defined by this crate)

  4. estebank commented on Jul 13, 2026

    @estebank
    Contributor

    Note that it is a hard problem to solve, any heuristic will be wrong in some cases and printing every possible name a type has been given can get quite verbose.

    The reason for preferring the "new" name is that if you go to the source looking for the origin of the error, you won't be finding the type as named originally otherwise if it got renamed. The original name in some cases is even unnameable (like std::foo::private::Bar reexported from std::foo::Bar).

    Re opening the ticket so that we can track discussion and any work related to this. This is related to #21934.

  5. Marcono1234 commented on Jul 13, 2026

    @Marcono1234
    Contributor

    Thanks for reopening!

    any heuristic will be wrong in some cases and printing every possible name a type has been given can get quite verbose

    Good point. If you think this is too difficult to solve or improve, or as intermediate solution, what do you think about my "note" / "hint" suggestion above?
    That is, keep the current behavior for now, but for every re-export the compiler message refers to (in the example here that is StdError only) mention the original type and by which crate the re-export is defined.
    Though private and doc hidden original types would be filtered out (this filtering already seems to exist for re-exports itself, see for example #153630).


    Also, could you please edit the title of this issue? It says "alias" but that might be confused with "type aliases" (type A = B), whereas the description is about re-exports. In fact, for "type aliases" the behavior seems to be the opposite currently, see #17164?

  6. changed the title [-]compiler error refers to dependency's alias for a std trait[/-] [+]Compiler error uses re-export name of not-imported crate for a std trait[/+] on Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`C-bugCategory: This is a bug.D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions