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