-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
#[derive(Debug)] fails when a generic parameter shares the name of the generic type #97343
Comments
Running with macro backtrace does not provide any enlightening information as the macro is a compiler builtin. |
use std::fmt::{Debug, Formatter};
pub struct Irrelevant<Irrelevant> {
irrelevant: Irrelevant,
}
impl<Irrelevant: Debug> Debug for Irrelevant<Irrelevant> {
fn fmt(&self, f: &mut Formatter) -> ::core::fmt::Result {
match self {
Irrelevant { irrelevant } => {
f.debug_struct("Irrelevant")
.field("irrelevant", irrelevant)
.finish()
}
}
}
} Expanding and cleaning up the expansion yields this, which causes the same errors. |
So I don't think this is a bug, since the issue is caused by exactly the name resolution specifics that allow the struct in the first place. So this is a bad diagnostic at worst. |
From my perspective this is indeed a bug. The built-in macro does not respect hygiene. The output can be fixed by prepending |
I agree. It's hard to see this as anything other than a bug, as I see it. |
Hm true, they could indeed use |
@rustbot claim |
Ah, what a shame, |
@fmease it predates it, it just had worse output:
The issue with the clashing of the literal struct inside of As a separate concern, I would like us to improve E0109 to account for this case and recommend you changing the type param |
Filed #97459 to improve E0574, while we're at it. |
Thinking about it for a second more, the macro could be smart enough to avoid using type param names that shadow the underlying type, but that might be too much magic for marginal improvements, I'll let @rust-lang/libs decide on that. For myself, I think that focusing on the errors themselves would yield enough benefit already. I personally would like to avoid writing code that looks like that, if a macro can be confused so can people. |
would that be user visible in any way?
I definitely agree with this. I think before we go about putting significant amounts of effort into improving this situation we should see some real examples that need the same name on the type and param. The |
I agree in principle for production code, but I can see how someone can end up with that code during development.
This code would start compiling. Any alternative |
…r=compiler-errors Modify `derive(Debug)` to use `Self` in struct literal to avoid redundant error Reduce verbosity in rust-lang#97343.
#97471 will also add a bit of context, but it isn't great yet:
|
I tried this code:
I expected to see this happen:
Code should compile normally as expected, with a correct
fmt::Debug
implementation. Omitting the derive shows that rustc accepts this as valid and intelligible code. We know that rustc is interpreting the type ofirrelevant
as the type parameter and not the parent struct, as the latter would produce an error since it would produce a recursive type with infinite size which would cause an error. As rustc defines the rust language, the derive macro should also handle this code correctly.Instead, this happened:
Compilation errors with the following diagnostic:
Meta
I tested this and got the same result on the following versions:
The text was updated successfully, but these errors were encountered: