Implement Diagnostic trait for rustc_errors::DecorateDiagCompat

This commit is contained in:
Guillaume Gomez
2026-03-03 17:21:16 +01:00
parent 1b7d722f42
commit 924748717b
2 changed files with 20 additions and 9 deletions
+5 -6
View File
@@ -1,15 +1,16 @@
/// This module provides types and traits for buffering lints until later in compilation.
use rustc_ast::node_id::NodeId;
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync::DynSend;
use rustc_error_messages::MultiSpan;
use rustc_lint_defs::{BuiltinLintDiag, Lint, LintId};
use crate::{DynSend, LintDiagnostic, LintDiagnosticBox};
use crate::{Diag, DiagCtxtHandle, Diagnostic, Level};
/// We can't implement `LintDiagnostic` for `BuiltinLintDiag`, because decorating some of its
/// variants requires types we don't have yet. So, handle that case separately.
pub enum DecorateDiagCompat {
Dynamic(Box<dyn for<'a> LintDiagnosticBox<'a, ()> + DynSend + 'static>),
Dynamic(Box<dyn for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + 'static>),
Builtin(BuiltinLintDiag),
}
@@ -19,12 +20,10 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
}
}
impl !LintDiagnostic<'_, ()> for BuiltinLintDiag {}
impl<D: for<'a> LintDiagnostic<'a, ()> + DynSend + 'static> From<D> for DecorateDiagCompat {
impl<D: for<'a> Diagnostic<'a, ()> + DynSend + 'static> From<D> for DecorateDiagCompat {
#[inline]
fn from(d: D) -> Self {
Self::Dynamic(Box::new(d))
Self::Dynamic(Box::new(|dcx, level| d.into_diag(dcx, level)))
}
}
+15 -3
View File
@@ -7,7 +7,10 @@
use rustc_ast::visit::{self as ast_visit, Visitor, walk_list};
use rustc_ast::{self as ast, AttrVec, HasAttrs};
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer};
use rustc_data_structures::sync::DynSend;
use rustc_errors::{
BufferedEarlyLint, DecorateDiagCompat, Diag, DiagCtxtHandle, Diagnostic, Level, LintBuffer,
};
use rustc_feature::Features;
use rustc_middle::ty::{RegisteredTools, TyCtxt};
use rustc_session::Session;
@@ -35,6 +38,16 @@ pub struct EarlyContextAndPass<'ecx, 'tcx, T: EarlyLintPass> {
impl<'ecx, 'tcx, T: EarlyLintPass> EarlyContextAndPass<'ecx, 'tcx, T> {
fn check_id(&mut self, id: ast::NodeId) {
struct BoxDiag(
Box<dyn for<'a> FnOnce(DiagCtxtHandle<'a>, Level) -> Diag<'a, ()> + DynSend + 'static>,
);
impl<'a> Diagnostic<'a, ()> for BoxDiag {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
(self.0)(dcx, level)
}
}
for early_lint in self.context.buffered.take(id) {
let BufferedEarlyLint { span, node_id: _, lint_id, diagnostic } = early_lint;
match diagnostic {
@@ -50,8 +63,7 @@ fn check_id(&mut self, id: ast::NodeId) {
);
}
DecorateDiagCompat::Dynamic(d) => {
self.context
.opt_span_lint(lint_id.lint, span, |diag| d.decorate_lint_box(diag));
self.context.opt_span_diag_lint(lint_id.lint, span, BoxDiag(d));
}
}
}