rustc_error_messages/
diagnostic_impls.rs

1use 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                    // Convert to a string if it won't fit into `Number`.
59                    #[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}