rustc_lint/early/
diagnostics.rs1use std::any::Any;
2
3use rustc_data_structures::sync::DynSend;
4use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, Level};
5use rustc_hir::lints::{AttributeLintKind, FormatWarning};
6use rustc_middle::ty::TyCtxt;
7use rustc_session::Session;
8
9use crate::lints;
10
11mod check_cfg;
12
13pub struct DiagAndSess<'sess> {
14 pub callback: Box<
15 dyn for<'b> FnOnce(DiagCtxtHandle<'b>, Level, &dyn Any) -> Diag<'b, ()> + DynSend + 'static,
16 >,
17 pub sess: &'sess Session,
18}
19
20impl<'a> Diagnostic<'a, ()> for DiagAndSess<'_> {
21 fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
22 (self.callback)(dcx, level, self.sess)
23 }
24}
25
26pub struct DecorateAttrLint<'a, 'sess, 'tcx> {
29 pub sess: &'sess Session,
30 pub tcx: Option<TyCtxt<'tcx>>,
31 pub diagnostic: &'a AttributeLintKind,
32}
33
34impl<'a> Diagnostic<'a, ()> for DecorateAttrLint<'_, '_, '_> {
35 fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, ()> {
36 match self.diagnostic {
37 &AttributeLintKind::UnexpectedCfgName(name, value) => {
38 check_cfg::unexpected_cfg_name(self.sess, self.tcx, name, value)
39 .into_diag(dcx, level)
40 }
41 &AttributeLintKind::UnexpectedCfgValue(name, value) => {
42 check_cfg::unexpected_cfg_value(self.sess, self.tcx, name, value)
43 .into_diag(dcx, level)
44 }
45
46 &AttributeLintKind::DocTestTakesList => lints::DocTestTakesList.into_diag(dcx, level),
47
48 &AttributeLintKind::DocTestUnknown { name } => {
49 lints::DocTestUnknown { name }.into_diag(dcx, level)
50 }
51
52 &AttributeLintKind::DocTestLiteral => lints::DocTestLiteral.into_diag(dcx, level),
53
54 &AttributeLintKind::AttrCrateLevelOnly => {
55 lints::AttrCrateLevelOnly.into_diag(dcx, level)
56 }
57
58 &AttributeLintKind::DoNotRecommendDoesNotExpectArgs => {
59 lints::DoNotRecommendDoesNotExpectArgs.into_diag(dcx, level)
60 }
61
62 &AttributeLintKind::CrateTypeUnknown { span, suggested } => lints::UnknownCrateTypes {
63 sugg: suggested.map(|s| lints::UnknownCrateTypesSuggestion { span, snippet: s }),
64 }
65 .into_diag(dcx, level),
66
67 &AttributeLintKind::MalformedDoc => lints::MalformedDoc.into_diag(dcx, level),
68
69 &AttributeLintKind::ExpectedNoArgs => lints::ExpectedNoArgs.into_diag(dcx, level),
70
71 &AttributeLintKind::ExpectedNameValue => lints::ExpectedNameValue.into_diag(dcx, level),
72 &AttributeLintKind::MalFormedDiagnosticAttribute { attribute, options, span } => {
73 lints::MalFormedDiagnosticAttributeLint { attribute, options, span }
74 .into_diag(dcx, level)
75 }
76
77 AttributeLintKind::MalformedDiagnosticFormat { warning } => match warning {
78 FormatWarning::PositionalArgument { .. } => {
79 lints::DisallowedPositionalArgument.into_diag(dcx, level)
80 }
81 FormatWarning::InvalidSpecifier { .. } => {
82 lints::InvalidFormatSpecifier.into_diag(dcx, level)
83 }
84 FormatWarning::DisallowedPlaceholder { .. } => {
85 lints::DisallowedPlaceholder.into_diag(dcx, level)
86 }
87 },
88 AttributeLintKind::DiagnosticWrappedParserError { description, label, span } => {
89 lints::WrappedParserError { description, label, span: *span }.into_diag(dcx, level)
90 }
91 &AttributeLintKind::IgnoredDiagnosticOption { option_name, first_span, later_span } => {
92 lints::IgnoredDiagnosticOption { option_name, first_span, later_span }
93 .into_diag(dcx, level)
94 }
95 &AttributeLintKind::MissingOptionsForDiagnosticAttribute { attribute, options } => {
96 lints::MissingOptionsForDiagnosticAttribute { attribute, options }
97 .into_diag(dcx, level)
98 }
99 &AttributeLintKind::NonMetaItemDiagnosticAttribute => {
100 lints::NonMetaItemDiagnosticAttribute.into_diag(dcx, level)
101 }
102 }
103 }
104}