Repository navigation
Compiler error uses re-export name of not-imported crate for a std trait #81973
Copy link
Copy link
Open
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`Area: Suggestions generated by the compiler applied by `cargo fix`C-bugCategory: This is a bug.Category: This is a bug.D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.Diagnostics: A diagnostic that is giving misleading or incorrect information.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
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.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
A-diagnosticsArea: Messages for errors, warnings, and lintsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`Area: Suggestions generated by the compiler applied by `cargo fix`C-bugCategory: This is a bug.Category: This is a bug.D-incorrectDiagnostics: A diagnostic that is giving misleading or incorrect information.Diagnostics: A diagnostic that is giving misleading or incorrect information.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Activity
estebank commentedon Aug 14, 2023
Current output:
Marcono1234 commentedon Jul 13, 2026
But now the error message refers to both
StdErrorandstd::error::Error, possibly causing even more confusion? It seems only the suggested code change has improved to refer tostd::error::Errornow instead ofStdError, but the rest of the error message still refers toStdError.The main problems are in my opinion:
(for
StdErrormaybe you can guess it, but that might not always be possible)In my case, even when I put the code referring to
std::error::Errorinlib.rs, it seems to suffice that some nested module somewhere imports Serde types to still cause the error message to refer to it asStdError.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:
estebank commentedon Jul 13, 2026
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::Barreexported fromstd::foo::Bar).Re opening the ticket so that we can track discussion and any work related to this. This is related to #21934.
Marcono1234 commentedon Jul 13, 2026
Thanks for reopening!
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
StdErroronly) 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?[-]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[/+]