rustc_errors/
decorate_diag.rs1use rustc_ast::node_id::NodeId;
3use rustc_data_structures::fx::FxIndexMap;
4use rustc_error_messages::MultiSpan;
5use rustc_lint_defs::{BuiltinLintDiag, Lint, LintId};
6
7use crate::{DynSend, LintDiagnostic, LintDiagnosticBox};
8
9pub enum DecorateDiagCompat {
12 Dynamic(Box<dyn for<'a> LintDiagnosticBox<'a, ()> + DynSend + 'static>),
13 Builtin(BuiltinLintDiag),
14}
15
16impl std::fmt::Debug for DecorateDiagCompat {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 f.debug_struct("DecorateDiagCompat").finish()
19 }
20}
21
22impl !LintDiagnostic<'_, ()> for BuiltinLintDiag {}
23
24impl<D: for<'a> LintDiagnostic<'a, ()> + DynSend + 'static> From<D> for DecorateDiagCompat {
25 #[inline]
26 fn from(d: D) -> Self {
27 Self::Dynamic(Box::new(d))
28 }
29}
30
31impl From<BuiltinLintDiag> for DecorateDiagCompat {
32 #[inline]
33 fn from(b: BuiltinLintDiag) -> Self {
34 Self::Builtin(b)
35 }
36}
37
38#[derive(Debug)]
41pub struct BufferedEarlyLint {
42 pub span: Option<MultiSpan>,
44
45 pub node_id: NodeId,
47
48 pub lint_id: LintId,
51
52 pub diagnostic: DecorateDiagCompat,
54}
55
56#[derive(Default, Debug)]
57pub struct LintBuffer {
58 pub map: FxIndexMap<NodeId, Vec<BufferedEarlyLint>>,
59}
60
61impl LintBuffer {
62 pub fn add_early_lint(&mut self, early_lint: BufferedEarlyLint) {
63 self.map.entry(early_lint.node_id).or_default().push(early_lint);
64 }
65
66 pub fn take(&mut self, id: NodeId) -> Vec<BufferedEarlyLint> {
67 self.map.swap_remove(&id).unwrap_or_default()
69 }
70
71 pub fn buffer_lint(
72 &mut self,
73 lint: &'static Lint,
74 node_id: NodeId,
75 span: impl Into<MultiSpan>,
76 decorate: impl Into<DecorateDiagCompat>,
77 ) {
78 self.add_early_lint(BufferedEarlyLint {
79 lint_id: LintId::of(lint),
80 node_id,
81 span: Some(span.into()),
82 diagnostic: decorate.into(),
83 });
84 }
85}