rustc_errors/
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_abi::TargetDataLayoutErrors;
9use rustc_ast::util::parser::ExprPrecedence;
10use rustc_ast_pretty::pprust;
11use rustc_attr_data_structures::RustcVersion;
12use rustc_macros::Subdiagnostic;
13use rustc_span::edition::Edition;
14use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol};
15use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTuple};
16use rustc_type_ir::{ClosureKind, FloatTy};
17use {rustc_ast as ast, rustc_hir as hir};
18
19use crate::diagnostic::DiagLocation;
20use crate::{
21    Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, ErrCode, IntoDiagArg, Level,
22    Subdiagnostic, fluent_generated as fluent,
23};
24
25pub struct DiagArgFromDisplay<'a>(pub &'a dyn fmt::Display);
26
27impl IntoDiagArg for DiagArgFromDisplay<'_> {
28    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
29        self.0.to_string().into_diag_arg(path)
30    }
31}
32
33impl<'a> From<&'a dyn fmt::Display> for DiagArgFromDisplay<'a> {
34    fn from(t: &'a dyn fmt::Display) -> Self {
35        DiagArgFromDisplay(t)
36    }
37}
38
39impl<'a, T: fmt::Display> From<&'a T> for DiagArgFromDisplay<'a> {
40    fn from(t: &'a T) -> Self {
41        DiagArgFromDisplay(t)
42    }
43}
44
45impl<'a, T: Clone + IntoDiagArg> IntoDiagArg for &'a T {
46    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
47        self.clone().into_diag_arg(path)
48    }
49}
50
51#[macro_export]
52macro_rules! into_diag_arg_using_display {
53    ($( $ty:ty ),+ $(,)?) => {
54        $(
55            impl IntoDiagArg for $ty {
56                fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
57                    self.to_string().into_diag_arg(path)
58                }
59            }
60        )+
61    }
62}
63
64macro_rules! into_diag_arg_for_number {
65    ($( $ty:ty ),+ $(,)?) => {
66        $(
67            impl IntoDiagArg for $ty {
68                fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
69                    // Convert to a string if it won't fit into `Number`.
70                    #[allow(irrefutable_let_patterns)]
71                    if let Ok(n) = TryInto::<i32>::try_into(self) {
72                        DiagArgValue::Number(n)
73                    } else {
74                        self.to_string().into_diag_arg(path)
75                    }
76                }
77            }
78        )+
79    }
80}
81
82into_diag_arg_using_display!(
83    ast::ParamKindOrd,
84    std::io::Error,
85    Box<dyn std::error::Error>,
86    std::num::NonZero<u32>,
87    hir::Target,
88    Edition,
89    Ident,
90    MacroRulesNormalizedIdent,
91    ParseIntError,
92    StackProtector,
93    &TargetTuple,
94    SplitDebuginfo,
95    ExitStatus,
96    ErrCode,
97    rustc_abi::ExternAbi,
98);
99
100impl IntoDiagArg for RustcVersion {
101    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
102        DiagArgValue::Str(Cow::Owned(self.to_string()))
103    }
104}
105
106impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::TraitRef<I> {
107    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
108        self.to_string().into_diag_arg(path)
109    }
110}
111
112impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::ExistentialTraitRef<I> {
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<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::UnevaluatedConst<I> {
119    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
120        format!("{self:?}").into_diag_arg(path)
121    }
122}
123
124impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::FnSig<I> {
125    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
126        format!("{self:?}").into_diag_arg(path)
127    }
128}
129
130impl<I: rustc_type_ir::Interner, T> IntoDiagArg for rustc_type_ir::Binder<I, T>
131where
132    T: IntoDiagArg,
133{
134    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
135        self.skip_binder().into_diag_arg(path)
136    }
137}
138
139into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
140
141impl IntoDiagArg for bool {
142    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
143        if self {
144            DiagArgValue::Str(Cow::Borrowed("true"))
145        } else {
146            DiagArgValue::Str(Cow::Borrowed("false"))
147        }
148    }
149}
150
151impl IntoDiagArg for char {
152    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
153        DiagArgValue::Str(Cow::Owned(format!("{self:?}")))
154    }
155}
156
157impl IntoDiagArg for Vec<char> {
158    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
159        DiagArgValue::StrListSepByAnd(
160            self.into_iter().map(|c| Cow::Owned(format!("{c:?}"))).collect(),
161        )
162    }
163}
164
165impl IntoDiagArg for Symbol {
166    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
167        self.to_ident_string().into_diag_arg(path)
168    }
169}
170
171impl<'a> IntoDiagArg for &'a str {
172    fn into_diag_arg(self, path: &mut Option<std::path::PathBuf>) -> DiagArgValue {
173        self.to_string().into_diag_arg(path)
174    }
175}
176
177impl IntoDiagArg for String {
178    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
179        DiagArgValue::Str(Cow::Owned(self))
180    }
181}
182
183impl<'a> IntoDiagArg for Cow<'a, str> {
184    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
185        DiagArgValue::Str(Cow::Owned(self.into_owned()))
186    }
187}
188
189impl<'a> IntoDiagArg for &'a Path {
190    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
191        DiagArgValue::Str(Cow::Owned(self.display().to_string()))
192    }
193}
194
195impl IntoDiagArg for PathBuf {
196    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
197        DiagArgValue::Str(Cow::Owned(self.display().to_string()))
198    }
199}
200
201impl IntoDiagArg for PanicStrategy {
202    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
203        DiagArgValue::Str(Cow::Owned(self.desc().to_string()))
204    }
205}
206
207impl IntoDiagArg for hir::ConstContext {
208    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
209        DiagArgValue::Str(Cow::Borrowed(match self {
210            hir::ConstContext::ConstFn => "const_fn",
211            hir::ConstContext::Static(_) => "static",
212            hir::ConstContext::Const { .. } => "const",
213        }))
214    }
215}
216
217impl IntoDiagArg for ast::Expr {
218    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
219        DiagArgValue::Str(Cow::Owned(pprust::expr_to_string(&self)))
220    }
221}
222
223impl IntoDiagArg for ast::Path {
224    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
225        DiagArgValue::Str(Cow::Owned(pprust::path_to_string(&self)))
226    }
227}
228
229impl IntoDiagArg for ast::token::Token {
230    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
231        DiagArgValue::Str(pprust::token_to_string(&self))
232    }
233}
234
235impl IntoDiagArg for ast::token::TokenKind {
236    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
237        DiagArgValue::Str(pprust::token_kind_to_string(&self))
238    }
239}
240
241impl IntoDiagArg for FloatTy {
242    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
243        DiagArgValue::Str(Cow::Borrowed(self.name_str()))
244    }
245}
246
247impl IntoDiagArg for std::ffi::CString {
248    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
249        DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
250    }
251}
252
253impl IntoDiagArg for rustc_data_structures::small_c_str::SmallCStr {
254    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
255        DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
256    }
257}
258
259impl IntoDiagArg for ast::Visibility {
260    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
261        let s = pprust::vis_to_string(&self);
262        let s = s.trim_end().to_string();
263        DiagArgValue::Str(Cow::Owned(s))
264    }
265}
266
267impl IntoDiagArg for rustc_lint_defs::Level {
268    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
269        DiagArgValue::Str(Cow::Borrowed(self.to_cmd_flag()))
270    }
271}
272
273impl<Id> IntoDiagArg for hir::def::Res<Id> {
274    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
275        DiagArgValue::Str(Cow::Borrowed(self.descr()))
276    }
277}
278
279impl IntoDiagArg for DiagLocation {
280    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
281        DiagArgValue::Str(Cow::from(self.to_string()))
282    }
283}
284
285impl IntoDiagArg for Backtrace {
286    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
287        DiagArgValue::Str(Cow::from(self.to_string()))
288    }
289}
290
291impl IntoDiagArg for Level {
292    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
293        DiagArgValue::Str(Cow::from(self.to_string()))
294    }
295}
296
297impl IntoDiagArg for ClosureKind {
298    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
299        DiagArgValue::Str(self.as_str().into())
300    }
301}
302
303impl IntoDiagArg for hir::def::Namespace {
304    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
305        DiagArgValue::Str(Cow::Borrowed(self.descr()))
306    }
307}
308
309impl IntoDiagArg for ExprPrecedence {
310    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
311        DiagArgValue::Number(self as i32)
312    }
313}
314
315#[derive(Clone)]
316pub struct DiagSymbolList<S = Symbol>(Vec<S>);
317
318impl<S> From<Vec<S>> for DiagSymbolList<S> {
319    fn from(v: Vec<S>) -> Self {
320        DiagSymbolList(v)
321    }
322}
323
324impl<S> FromIterator<S> for DiagSymbolList<S> {
325    fn from_iter<T: IntoIterator<Item = S>>(iter: T) -> Self {
326        iter.into_iter().collect::<Vec<_>>().into()
327    }
328}
329
330impl<S: std::fmt::Display> IntoDiagArg for DiagSymbolList<S> {
331    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
332        DiagArgValue::StrListSepByAnd(
333            self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(),
334        )
335    }
336}
337
338impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetDataLayoutErrors<'_> {
339    fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
340        match self {
341            TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
342                Diag::new(dcx, level, fluent::errors_target_invalid_address_space)
343                    .with_arg("addr_space", addr_space)
344                    .with_arg("cause", cause)
345                    .with_arg("err", err)
346            }
347            TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
348                Diag::new(dcx, level, fluent::errors_target_invalid_bits)
349                    .with_arg("kind", kind)
350                    .with_arg("bit", bit)
351                    .with_arg("cause", cause)
352                    .with_arg("err", err)
353            }
354            TargetDataLayoutErrors::MissingAlignment { cause } => {
355                Diag::new(dcx, level, fluent::errors_target_missing_alignment)
356                    .with_arg("cause", cause)
357            }
358            TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
359                Diag::new(dcx, level, fluent::errors_target_invalid_alignment)
360                    .with_arg("cause", cause)
361                    .with_arg("err_kind", err.diag_ident())
362                    .with_arg("align", err.align())
363            }
364            TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
365                Diag::new(dcx, level, fluent::errors_target_inconsistent_architecture)
366                    .with_arg("dl", dl)
367                    .with_arg("target", target)
368            }
369            TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
370                Diag::new(dcx, level, fluent::errors_target_inconsistent_pointer_width)
371                    .with_arg("pointer_size", pointer_size)
372                    .with_arg("target", target)
373            }
374            TargetDataLayoutErrors::InvalidBitsSize { err } => {
375                Diag::new(dcx, level, fluent::errors_target_invalid_bits_size).with_arg("err", err)
376            }
377        }
378    }
379}
380
381/// Utility struct used to apply a single label while highlighting multiple spans
382pub struct SingleLabelManySpans {
383    pub spans: Vec<Span>,
384    pub label: &'static str,
385}
386impl Subdiagnostic for SingleLabelManySpans {
387    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
388        diag.span_labels(self.spans, self.label);
389    }
390}
391
392#[derive(Subdiagnostic)]
393#[label(errors_expected_lifetime_parameter)]
394pub struct ExpectedLifetimeParameter {
395    #[primary_span]
396    pub span: Span,
397    pub count: usize,
398}
399
400#[derive(Subdiagnostic)]
401#[suggestion(errors_indicate_anonymous_lifetime, code = "{suggestion}", style = "verbose")]
402pub struct IndicateAnonymousLifetime {
403    #[primary_span]
404    pub span: Span,
405    pub count: usize,
406    pub suggestion: String,
407}
408
409#[derive(Subdiagnostic)]
410pub struct ElidedLifetimeInPathSubdiag {
411    #[subdiagnostic]
412    pub expected: ExpectedLifetimeParameter,
413    #[subdiagnostic]
414    pub indicate: Option<IndicateAnonymousLifetime>,
415}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy