rune/diagnostics/
warning.rs
1use core::fmt;
2
3use crate::alloc::String;
4use crate::ast::Span;
5use crate::ast::Spanned;
6use crate::SourceId;
7
8#[derive(Debug)]
11pub struct WarningDiagnostic {
12 pub(crate) source_id: SourceId,
14 pub(crate) kind: WarningDiagnosticKind,
16}
17
18impl WarningDiagnostic {
19 pub fn source_id(&self) -> SourceId {
21 self.source_id
22 }
23
24 #[cfg(feature = "emit")]
26 pub(crate) fn kind(&self) -> &WarningDiagnosticKind {
27 &self.kind
28 }
29
30 #[cfg(test)]
31 pub(crate) fn into_kind(self) -> WarningDiagnosticKind {
32 self.kind
33 }
34
35 #[cfg(feature = "emit")]
37 pub(crate) fn context(&self) -> Option<Span> {
38 match &self.kind {
39 WarningDiagnosticKind::LetPatternMightPanic { context, .. }
40 | WarningDiagnosticKind::RemoveTupleCallParams { context, .. }
41 | WarningDiagnosticKind::NotUsed { context, .. }
42 | WarningDiagnosticKind::UsedDeprecated { context, .. }
43 | WarningDiagnosticKind::TemplateWithoutExpansions { context, .. } => *context,
44 _ => None,
45 }
46 }
47}
48
49impl Spanned for WarningDiagnostic {
50 fn span(&self) -> Span {
52 match &self.kind {
53 WarningDiagnosticKind::NotUsed { span, .. } => *span,
54 WarningDiagnosticKind::Unreachable { span, .. } => *span,
55 WarningDiagnosticKind::LetPatternMightPanic { span, .. } => *span,
56 WarningDiagnosticKind::TemplateWithoutExpansions { span, .. } => *span,
57 WarningDiagnosticKind::RemoveTupleCallParams { span, .. } => *span,
58 WarningDiagnosticKind::UnnecessarySemiColon { span, .. } => *span,
59 WarningDiagnosticKind::UsedDeprecated { span, .. } => *span,
60 }
61 }
62}
63
64impl fmt::Display for WarningDiagnostic {
65 #[inline]
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 fmt::Display::fmt(&self.kind, f)
68 }
69}
70
71impl core::error::Error for WarningDiagnostic {
72 #[inline]
73 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
74 None
75 }
76}
77
78#[derive(Debug)]
80#[allow(missing_docs)]
81#[non_exhaustive]
82pub(crate) enum WarningDiagnosticKind {
83 NotUsed {
85 span: Span,
87 #[cfg_attr(not(feature = "emit"), allow(dead_code))]
89 context: Option<Span>,
90 },
91 Unreachable {
93 span: Span,
95 #[cfg_attr(not(feature = "emit"), allow(dead_code))]
97 cause: Span,
98 },
99 LetPatternMightPanic {
102 span: Span,
104 #[cfg_attr(not(feature = "emit"), allow(dead_code))]
106 context: Option<Span>,
107 },
108 TemplateWithoutExpansions {
110 span: Span,
112 #[cfg_attr(not(feature = "emit"), allow(dead_code))]
114 context: Option<Span>,
115 },
116 RemoveTupleCallParams {
118 span: Span,
120 #[cfg_attr(not(feature = "emit"), allow(dead_code))]
122 variant: Span,
123 #[cfg_attr(not(feature = "emit"), allow(dead_code))]
125 context: Option<Span>,
126 },
127 UnnecessarySemiColon {
129 span: Span,
131 },
132 UsedDeprecated {
133 span: Span,
135 #[cfg_attr(not(feature = "emit"), allow(dead_code))]
137 context: Option<Span>,
138 message: String,
140 },
141}
142
143impl fmt::Display for WarningDiagnosticKind {
144 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
145 match self {
146 WarningDiagnosticKind::NotUsed { .. } => write!(f, "Not used"),
147 WarningDiagnosticKind::Unreachable { .. } => write!(f, "Unreachable code"),
148 WarningDiagnosticKind::LetPatternMightPanic { .. } => {
149 write!(f, "Pattern might panic")
150 }
151 WarningDiagnosticKind::TemplateWithoutExpansions { .. } => write!(
152 f,
153 "Using a template string without expansions, like `Hello World`"
154 ),
155 WarningDiagnosticKind::RemoveTupleCallParams { .. } => {
156 write!(f, "Call paramters are not needed here")
157 }
158 WarningDiagnosticKind::UnnecessarySemiColon { .. } => {
159 write!(f, "Unnecessary semicolon")
160 }
161 WarningDiagnosticKind::UsedDeprecated { message, .. } => {
162 write!(f, "Used deprecated function: {message}")
163 }
164 }
165 }
166}