Skip to main content

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_data_structures::Limit;
9use rustc_span::edition::Edition;
10
11use crate::{DiagArgValue, IntoDiagArg};
12
13pub struct DiagArgFromDisplay<'a>(pub &'a dyn fmt::Display);
14
15impl IntoDiagArg for DiagArgFromDisplay<'_> {
16    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
17        self.0.to_string().into_diag_arg(path)
18    }
19}
20
21impl<'a> From<&'a dyn fmt::Display> for DiagArgFromDisplay<'a> {
22    fn from(t: &'a dyn fmt::Display) -> Self {
23        DiagArgFromDisplay(t)
24    }
25}
26
27impl<'a, T: fmt::Display> From<&'a T> for DiagArgFromDisplay<'a> {
28    fn from(t: &'a T) -> Self {
29        DiagArgFromDisplay(t)
30    }
31}
32
33impl<'a, T: Clone + IntoDiagArg> IntoDiagArg for &'a T {
34    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
35        self.clone().into_diag_arg(path)
36    }
37}
38
39#[macro_export]
40macro_rules! into_diag_arg_using_display {
41    ($( $ty:ty ),+ $(,)?) => {
42        $(
43            impl $crate::IntoDiagArg for $ty {
44                fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> $crate::DiagArgValue {
45                    self.to_string().into_diag_arg(path)
46                }
47            }
48        )+
49    }
50}
51
52macro_rules! into_diag_arg_for_number {
53    ($( $ty:ty ),+ $(,)?) => {
54        $(
55            impl $crate::IntoDiagArg for $ty {
56                fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> $crate::DiagArgValue {
57                    // Convert to a string if it won't fit into `Number`.
58                    #[allow(irrefutable_let_patterns)]
59                    if let Ok(n) = TryInto::<i32>::try_into(self) {
60                        $crate::DiagArgValue::Number(n)
61                    } else {
62                        self.to_string().into_diag_arg(path)
63                    }
64                }
65            }
66        )+
67    }
68}
69
70impl crate::IntoDiagArg for ExitStatus {
    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>)
        -> crate::DiagArgValue {
        self.to_string().into_diag_arg(path)
    }
}into_diag_arg_using_display!(
71    std::io::Error,
72    Box<dyn std::error::Error>,
73    std::num::NonZero<u32>,
74    Edition,
75    rustc_span::Ident,
76    rustc_span::MacroRulesNormalizedIdent,
77    ParseIntError,
78    ExitStatus,
79);
80
81impl crate::IntoDiagArg for usize {
    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>)
        -> crate::DiagArgValue {

        #[allow(irrefutable_let_patterns)]
        if let Ok(n) = TryInto::<i32>::try_into(self) {
            crate::DiagArgValue::Number(n)
        } else { self.to_string().into_diag_arg(path) }
    }
}into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
82
83impl IntoDiagArg for bool {
84    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
85        if self {
86            DiagArgValue::Str(Cow::Borrowed("true"))
87        } else {
88            DiagArgValue::Str(Cow::Borrowed("false"))
89        }
90    }
91}
92
93impl IntoDiagArg for char {
94    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
95        DiagArgValue::Str(Cow::Owned(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", self))
    })format!("{self:?}")))
96    }
97}
98
99impl IntoDiagArg for Vec<char> {
100    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
101        DiagArgValue::StrListSepByAnd(
102            self.into_iter().map(|c| Cow::Owned(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", c))
    })format!("{c:?}"))).collect(),
103        )
104    }
105}
106
107impl IntoDiagArg for rustc_span::Symbol {
108    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
109        self.to_ident_string().into_diag_arg(path)
110    }
111}
112
113impl<'a> IntoDiagArg for &'a str {
114    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
115        self.to_string().into_diag_arg(path)
116    }
117}
118
119impl IntoDiagArg for String {
120    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
121        DiagArgValue::Str(Cow::Owned(self))
122    }
123}
124
125impl<'a> IntoDiagArg for Cow<'a, str> {
126    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
127        DiagArgValue::Str(Cow::Owned(self.into_owned()))
128    }
129}
130
131impl<'a> IntoDiagArg for &'a Path {
132    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
133        DiagArgValue::Str(Cow::Owned(self.display().to_string()))
134    }
135}
136
137impl IntoDiagArg for PathBuf {
138    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
139        DiagArgValue::Str(Cow::Owned(self.display().to_string()))
140    }
141}
142
143impl IntoDiagArg for std::ffi::CString {
144    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
145        DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
146    }
147}
148
149impl IntoDiagArg for rustc_data_structures::small_c_str::SmallCStr {
150    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
151        DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
152    }
153}
154
155impl IntoDiagArg for Backtrace {
156    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
157        DiagArgValue::Str(Cow::from(self.to_string()))
158    }
159}
160
161impl IntoDiagArg for Limit {
162    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
163        self.0.into_diag_arg(&mut None)
164    }
165}