Description
openedon May 15, 2024
In #117164 I had to copy the diagnostic structs TyParamFirstLocal
and TyParamSome
and define the separate structs TyParamFirstLocalLint
and TyParamSomeLint
to be able to use the translatable diagnostics hir_analysis_ty_param_first_local
and hir_analysis_ty_param_some
as both a Diagnostic
and a LintDiagnostic
:
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 structs ReprConflicting
and ReprConflictingLint
to be able to use the translatable diagnostic passes_repr_conflicting
as both a Diagnostic
and a LintDiagnostic
:
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 macro Diagnostic
, then the derive macro LintDiagnostic
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 like emit_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.