rustc_error_messages/
diagnostic_impls.rs1use std::backtrace::Backtrace;
2use std::borrow::Cow;
3use std::fmt;
4use std::num::ParseIntError;
5use std::path::{Path, PathBuf};
6use std::process::ExitStatus;
7
8use rustc_ast as ast;
9use rustc_ast_pretty::pprust;
10use rustc_span::edition::Edition;
11
12use crate::{DiagArgValue, IntoDiagArg};
13
14pub struct DiagArgFromDisplay<'a>(pub &'a dyn fmt::Display);
15
16impl IntoDiagArg for DiagArgFromDisplay<'_> {
17 fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
18 self.0.to_string().into_diag_arg(path)
19 }
20}
21
22impl<'a> From<&'a dyn fmt::Display> for DiagArgFromDisplay<'a> {
23 fn from(t: &'a dyn fmt::Display) -> Self {
24 DiagArgFromDisplay(t)
25 }
26}
27
28impl<'a, T: fmt::Display> From<&'a T> for DiagArgFromDisplay<'a> {
29 fn from(t: &'a T) -> Self {
30 DiagArgFromDisplay(t)
31 }
32}
33
34impl<'a, T: Clone + IntoDiagArg> IntoDiagArg for &'a T {
35 fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
36 self.clone().into_diag_arg(path)
37 }
38}
39
40#[macro_export]
41macro_rules! into_diag_arg_using_display {
42 ($( $ty:ty ),+ $(,)?) => {
43 $(
44 impl $crate::IntoDiagArg for $ty {
45 fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> $crate::DiagArgValue {
46 self.to_string().into_diag_arg(path)
47 }
48 }
49 )+
50 }
51}
52
53macro_rules! into_diag_arg_for_number {
54 ($( $ty:ty ),+ $(,)?) => {
55 $(
56 impl $crate::IntoDiagArg for $ty {
57 fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> $crate::DiagArgValue {
58 #[allow(irrefutable_let_patterns)]
60 if let Ok(n) = TryInto::<i32>::try_into(self) {
61 $crate::DiagArgValue::Number(n)
62 } else {
63 self.to_string().into_diag_arg(path)
64 }
65 }
66 }
67 )+
68 }
69}
70
71into_diag_arg_using_display!(
72 ast::ParamKindOrd,
73 std::io::Error,
74 Box<dyn std::error::Error>,
75 std::num::NonZero<u32>,
76 Edition,
77 rustc_span::Ident,
78 rustc_span::MacroRulesNormalizedIdent,
79 ParseIntError,
80 ExitStatus,
81);
82
83into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
84
85impl IntoDiagArg for bool {
86 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
87 if self {
88 DiagArgValue::Str(Cow::Borrowed("true"))
89 } else {
90 DiagArgValue::Str(Cow::Borrowed("false"))
91 }
92 }
93}
94
95impl IntoDiagArg for char {
96 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
97 DiagArgValue::Str(Cow::Owned(format!("{self:?}")))
98 }
99}
100
101impl IntoDiagArg for Vec<char> {
102 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
103 DiagArgValue::StrListSepByAnd(
104 self.into_iter().map(|c| Cow::Owned(format!("{c:?}"))).collect(),
105 )
106 }
107}
108
109impl IntoDiagArg for rustc_span::Symbol {
110 fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
111 self.to_ident_string().into_diag_arg(path)
112 }
113}
114
115impl<'a> IntoDiagArg for &'a str {
116 fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
117 self.to_string().into_diag_arg(path)
118 }
119}
120
121impl IntoDiagArg for String {
122 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
123 DiagArgValue::Str(Cow::Owned(self))
124 }
125}
126
127impl<'a> IntoDiagArg for Cow<'a, str> {
128 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
129 DiagArgValue::Str(Cow::Owned(self.into_owned()))
130 }
131}
132
133impl<'a> IntoDiagArg for &'a Path {
134 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
135 DiagArgValue::Str(Cow::Owned(self.display().to_string()))
136 }
137}
138
139impl IntoDiagArg for PathBuf {
140 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
141 DiagArgValue::Str(Cow::Owned(self.display().to_string()))
142 }
143}
144
145impl IntoDiagArg for ast::Expr {
146 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
147 DiagArgValue::Str(Cow::Owned(pprust::expr_to_string(&self)))
148 }
149}
150
151impl IntoDiagArg for ast::Path {
152 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
153 DiagArgValue::Str(Cow::Owned(pprust::path_to_string(&self)))
154 }
155}
156
157impl IntoDiagArg for ast::token::Token {
158 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
159 DiagArgValue::Str(pprust::token_to_string(&self))
160 }
161}
162
163impl IntoDiagArg for ast::token::TokenKind {
164 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
165 DiagArgValue::Str(pprust::token_kind_to_string(&self))
166 }
167}
168
169impl IntoDiagArg for std::ffi::CString {
170 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
171 DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
172 }
173}
174
175impl IntoDiagArg for rustc_data_structures::small_c_str::SmallCStr {
176 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
177 DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
178 }
179}
180
181impl IntoDiagArg for ast::Visibility {
182 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
183 let s = pprust::vis_to_string(&self);
184 let s = s.trim_end().to_string();
185 DiagArgValue::Str(Cow::Owned(s))
186 }
187}
188
189impl IntoDiagArg for Backtrace {
190 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
191 DiagArgValue::Str(Cow::from(self.to_string()))
192 }
193}
194
195impl IntoDiagArg for ast::util::parser::ExprPrecedence {
196 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
197 DiagArgValue::Number(self as i32)
198 }
199}
200
201impl IntoDiagArg for ast::FloatTy {
202 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
203 DiagArgValue::Str(Cow::Borrowed(self.name_str()))
204 }
205}