rustc_macros
: Make it possible to derive both Diagnostic
and LintDiagnostic
on the same type
#125169
Labels
A-contributor-roadblock
Area: Makes things more difficult for new contributors to rust itself
A-lint
Area: Lints (warnings about flaws in source code) such as unused_mut.
A-translation
Area: Translation infrastructure, and migrating existing diagnostics to SessionDiagnostic
C-enhancement
Category: An issue proposing an enhancement or a PR with one.
T-compiler
Relevant to the compiler team, which will review and decide on the PR/issue.
In #117164 I had to copy the diagnostic structs
TyParamFirstLocal
andTyParamSome
and define the separate structsTyParamFirstLocalLint
andTyParamSomeLint
to be able to use the translatable diagnosticshir_analysis_ty_param_first_local
andhir_analysis_ty_param_some
as both aDiagnostic
and aLintDiagnostic
:rust/compiler/rustc_hir_analysis/src/errors.rs
Lines 1360 to 1406 in b21b74b
In #116829, had to duplicate the lint diagnostic struct
ReprConflicting
and split it into the separate structsReprConflicting
andReprConflictingLint
to be able to use the translatable diagnosticpasses_repr_conflicting
as both aDiagnostic
and aLintDiagnostic
:rust/compiler/rustc_passes/src/errors.rs
Lines 554 to 563 in b21b74b
In all three cases, I could've probably turned the derivation of
LintDiagnostic
into a manual impl but that doesn't seem very enticing either for various reasons.For context, this situation arises whenever we want to emit a diagnostic for something but can't report a hard error unconditionally in all cases for backward compatibility and therefore have to emit the very same diagnostic at different “levels of severity” depending on a set of conditions. With level of severity I'm specifically referring to the set {hard error, lint} here (where lint has its own level of course).
More concretely, the reason why you can't just
#[derive(Diagnostic, LintDiagnostic)] struct Ty/*...*/
is because of#[primary_span]
: If the diagnostic struct contains a#[primary_span]
(which it does most of the time) for the derive macroDiagnostic
, then the derive macroLintDiagnostic
will reject#[primary_span]
rendering the two derives incompatible with one another.Individually,
LintDiagnostic
rejecting#[primary_span]
makes sense because the span(s) for a lint are to be provided to the function that emits the lint likeemit_span_lint
,emit_node_span_lint
.There are probably multiple ways to approach this but I'm not super familiar with internals of rustc's linting API. Anyways, I'd like to see this “just work” because it won't be the last time this case will occur.
The text was updated successfully, but these errors were encountered: