]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_errors/src/diagnostic_impls.rs
Auto merge of #103556 - clubby789:specialize-option-partial-eq, r=scottmcm
[rust.git] / compiler / rustc_errors / src / diagnostic_impls.rs
1 use crate::{
2     fluent, DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg,
3 };
4 use rustc_ast as ast;
5 use rustc_ast_pretty::pprust;
6 use rustc_hir as hir;
7 use rustc_lint_defs::Level;
8 use rustc_span::edition::Edition;
9 use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
10 use rustc_target::abi::TargetDataLayoutErrors;
11 use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
12 use std::borrow::Cow;
13 use std::fmt;
14 use std::num::ParseIntError;
15 use std::path::{Path, PathBuf};
16 use std::process::ExitStatus;
17
18 pub struct DiagnosticArgFromDisplay<'a>(pub &'a dyn fmt::Display);
19
20 impl IntoDiagnosticArg for DiagnosticArgFromDisplay<'_> {
21     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
22         self.0.to_string().into_diagnostic_arg()
23     }
24 }
25
26 impl<'a> From<&'a dyn fmt::Display> for DiagnosticArgFromDisplay<'a> {
27     fn from(t: &'a dyn fmt::Display) -> Self {
28         DiagnosticArgFromDisplay(t)
29     }
30 }
31
32 impl<'a, T: fmt::Display> From<&'a T> for DiagnosticArgFromDisplay<'a> {
33     fn from(t: &'a T) -> Self {
34         DiagnosticArgFromDisplay(t)
35     }
36 }
37
38 macro_rules! into_diagnostic_arg_using_display {
39     ($( $ty:ty ),+ $(,)?) => {
40         $(
41             impl IntoDiagnosticArg for $ty {
42                 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
43                     self.to_string().into_diagnostic_arg()
44                 }
45             }
46         )+
47     }
48 }
49
50 into_diagnostic_arg_using_display!(
51     i8,
52     u8,
53     i16,
54     u16,
55     i32,
56     u32,
57     i64,
58     u64,
59     i128,
60     u128,
61     std::io::Error,
62     std::boxed::Box<dyn std::error::Error>,
63     std::num::NonZeroU32,
64     hir::Target,
65     Edition,
66     Ident,
67     MacroRulesNormalizedIdent,
68     ParseIntError,
69     StackProtector,
70     &TargetTriple,
71     SplitDebuginfo,
72     ExitStatus,
73 );
74
75 impl IntoDiagnosticArg for bool {
76     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
77         if self {
78             DiagnosticArgValue::Str(Cow::Borrowed("true"))
79         } else {
80             DiagnosticArgValue::Str(Cow::Borrowed("false"))
81         }
82     }
83 }
84
85 impl IntoDiagnosticArg for char {
86     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
87         DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self)))
88     }
89 }
90
91 impl IntoDiagnosticArg for Symbol {
92     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
93         self.to_ident_string().into_diagnostic_arg()
94     }
95 }
96
97 impl<'a> IntoDiagnosticArg for &'a str {
98     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
99         self.to_string().into_diagnostic_arg()
100     }
101 }
102
103 impl IntoDiagnosticArg for String {
104     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
105         DiagnosticArgValue::Str(Cow::Owned(self))
106     }
107 }
108
109 impl<'a> IntoDiagnosticArg for Cow<'a, str> {
110     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
111         DiagnosticArgValue::Str(Cow::Owned(self.into_owned()))
112     }
113 }
114
115 impl<'a> IntoDiagnosticArg for &'a Path {
116     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
117         DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
118     }
119 }
120
121 impl IntoDiagnosticArg for PathBuf {
122     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
123         DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
124     }
125 }
126
127 impl IntoDiagnosticArg for usize {
128     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
129         DiagnosticArgValue::Number(self)
130     }
131 }
132
133 impl IntoDiagnosticArg for PanicStrategy {
134     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
135         DiagnosticArgValue::Str(Cow::Owned(self.desc().to_string()))
136     }
137 }
138
139 impl IntoDiagnosticArg for hir::ConstContext {
140     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
141         DiagnosticArgValue::Str(Cow::Borrowed(match self {
142             hir::ConstContext::ConstFn => "constant function",
143             hir::ConstContext::Static(_) => "static",
144             hir::ConstContext::Const => "constant",
145         }))
146     }
147 }
148
149 impl IntoDiagnosticArg for ast::Path {
150     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
151         DiagnosticArgValue::Str(Cow::Owned(pprust::path_to_string(&self)))
152     }
153 }
154
155 impl IntoDiagnosticArg for ast::token::Token {
156     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
157         DiagnosticArgValue::Str(pprust::token_to_string(&self))
158     }
159 }
160
161 impl IntoDiagnosticArg for ast::token::TokenKind {
162     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
163         DiagnosticArgValue::Str(pprust::token_kind_to_string(&self))
164     }
165 }
166
167 impl IntoDiagnosticArg for Level {
168     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
169         DiagnosticArgValue::Str(Cow::Borrowed(match self {
170             Level::Allow => "-A",
171             Level::Warn => "-W",
172             Level::ForceWarn(_) => "--force-warn",
173             Level::Deny => "-D",
174             Level::Forbid => "-F",
175             Level::Expect(_) => {
176                 unreachable!("lints with the level of `expect` should not run this code");
177             }
178         }))
179     }
180 }
181
182 #[derive(Clone)]
183 pub struct DiagnosticSymbolList(Vec<Symbol>);
184
185 impl From<Vec<Symbol>> for DiagnosticSymbolList {
186     fn from(v: Vec<Symbol>) -> Self {
187         DiagnosticSymbolList(v)
188     }
189 }
190
191 impl IntoDiagnosticArg for DiagnosticSymbolList {
192     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
193         DiagnosticArgValue::StrListSepByAnd(
194             self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(),
195         )
196     }
197 }
198
199 impl<Id> IntoDiagnosticArg for hir::def::Res<Id> {
200     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
201         DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
202     }
203 }
204
205 impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
206     fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> {
207         let mut diag;
208         match self {
209             TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
210                 diag = handler.struct_fatal(fluent::errors_target_invalid_address_space);
211                 diag.set_arg("addr_space", addr_space);
212                 diag.set_arg("cause", cause);
213                 diag.set_arg("err", err);
214                 diag
215             }
216             TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
217                 diag = handler.struct_fatal(fluent::errors_target_invalid_bits);
218                 diag.set_arg("kind", kind);
219                 diag.set_arg("bit", bit);
220                 diag.set_arg("cause", cause);
221                 diag.set_arg("err", err);
222                 diag
223             }
224             TargetDataLayoutErrors::MissingAlignment { cause } => {
225                 diag = handler.struct_fatal(fluent::errors_target_missing_alignment);
226                 diag.set_arg("cause", cause);
227                 diag
228             }
229             TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
230                 diag = handler.struct_fatal(fluent::errors_target_invalid_alignment);
231                 diag.set_arg("cause", cause);
232                 diag.set_arg("err", err);
233                 diag
234             }
235             TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
236                 diag = handler.struct_fatal(fluent::errors_target_inconsistent_architecture);
237                 diag.set_arg("dl", dl);
238                 diag.set_arg("target", target);
239                 diag
240             }
241             TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
242                 diag = handler.struct_fatal(fluent::errors_target_inconsistent_pointer_width);
243                 diag.set_arg("pointer_size", pointer_size);
244                 diag.set_arg("target", target);
245                 diag
246             }
247             TargetDataLayoutErrors::InvalidBitsSize { err } => {
248                 diag = handler.struct_fatal(fluent::errors_target_invalid_bits_size);
249                 diag.set_arg("err", err);
250                 diag
251             }
252         }
253     }
254 }