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