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_span::edition::Edition;
9
10use crate::{DiagArgValue, IntoDiagArg};
11
12pub struct DiagArgFromDisplay<'a>(pub &'a dyn fmt::Display);
13
14impl IntoDiagArg for DiagArgFromDisplay<'_> {
15    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
16        self.0.to_string().into_diag_arg(path)
17    }
18}
19
20impl<'a> From<&'a dyn fmt::Display> for DiagArgFromDisplay<'a> {
21    fn from(t: &'a dyn fmt::Display) -> Self {
22        DiagArgFromDisplay(t)
23    }
24}
25
26impl<'a, T: fmt::Display> From<&'a T> for DiagArgFromDisplay<'a> {
27    fn from(t: &'a T) -> Self {
28        DiagArgFromDisplay(t)
29    }
30}
31
32impl<'a, T: Clone + IntoDiagArg> IntoDiagArg for &'a T {
33    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
34        self.clone().into_diag_arg(path)
35    }
36}
37
38#[macro_export]
39macro_rules! into_diag_arg_using_display {
40    ($( $ty:ty ),+ $(,)?) => {
41        $(
42            impl $crate::IntoDiagArg for $ty {
43                fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> $crate::DiagArgValue {
44                    self.to_string().into_diag_arg(path)
45                }
46            }
47        )+
48    }
49}
50
51macro_rules! into_diag_arg_for_number {
52    ($( $ty:ty ),+ $(,)?) => {
53        $(
54            impl $crate::IntoDiagArg for $ty {
55                fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> $crate::DiagArgValue {
56                    // Convert to a string if it won't fit into `Number`.
57                    #[allow(irrefutable_let_patterns)]
58                    if let Ok(n) = TryInto::<i32>::try_into(self) {
59                        $crate::DiagArgValue::Number(n)
60                    } else {
61                        self.to_string().into_diag_arg(path)
62                    }
63                }
64            }
65        )+
66    }
67}
68
69impl 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!(
70    std::io::Error,
71    Box<dyn std::error::Error>,
72    std::num::NonZero<u32>,
73    Edition,
74    rustc_span::Ident,
75    rustc_span::MacroRulesNormalizedIdent,
76    ParseIntError,
77    ExitStatus,
78);
79
80impl 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);
81
82impl IntoDiagArg for bool {
83    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
84        if self {
85            DiagArgValue::Str(Cow::Borrowed("true"))
86        } else {
87            DiagArgValue::Str(Cow::Borrowed("false"))
88        }
89    }
90}
91
92impl IntoDiagArg for char {
93    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
94        DiagArgValue::Str(Cow::Owned(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", self))
    })format!("{self:?}")))
95    }
96}
97
98impl IntoDiagArg for Vec<char> {
99    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
100        DiagArgValue::StrListSepByAnd(
101            self.into_iter().map(|c| Cow::Owned(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:?}", c))
    })format!("{c:?}"))).collect(),
102        )
103    }
104}
105
106impl IntoDiagArg for rustc_span::Symbol {
107    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
108        self.to_ident_string().into_diag_arg(path)
109    }
110}
111
112impl<'a> IntoDiagArg for &'a str {
113    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
114        self.to_string().into_diag_arg(path)
115    }
116}
117
118impl IntoDiagArg for String {
119    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
120        DiagArgValue::Str(Cow::Owned(self))
121    }
122}
123
124impl<'a> IntoDiagArg for Cow<'a, str> {
125    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
126        DiagArgValue::Str(Cow::Owned(self.into_owned()))
127    }
128}
129
130impl<'a> IntoDiagArg for &'a Path {
131    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
132        DiagArgValue::Str(Cow::Owned(self.display().to_string()))
133    }
134}
135
136impl IntoDiagArg for PathBuf {
137    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
138        DiagArgValue::Str(Cow::Owned(self.display().to_string()))
139    }
140}
141
142impl IntoDiagArg for std::ffi::CString {
143    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
144        DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
145    }
146}
147
148impl IntoDiagArg for rustc_data_structures::small_c_str::SmallCStr {
149    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
150        DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
151    }
152}
153
154impl IntoDiagArg for Backtrace {
155    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
156        DiagArgValue::Str(Cow::from(self.to_string()))
157    }
158}