Skip to main content

rustc_errors/
diagnostic_impls.rs

1use std::borrow::Cow;
2
3use rustc_abi::TargetDataLayoutErrors;
4use rustc_error_messages::{DiagArgValue, IntoDiagArg};
5use rustc_macros::Subdiagnostic;
6use rustc_span::{Span, Symbol};
7
8use crate::diagnostic::DiagLocation;
9use crate::{
10    Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, Subdiagnostic, inline_fluent,
11};
12
13impl IntoDiagArg for DiagLocation {
14    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
15        DiagArgValue::Str(Cow::from(self.to_string()))
16    }
17}
18
19#[derive(#[automatically_derived]
impl<S: ::core::clone::Clone> ::core::clone::Clone for DiagSymbolList<S> {
    #[inline]
    fn clone(&self) -> DiagSymbolList<S> {
        DiagSymbolList(::core::clone::Clone::clone(&self.0))
    }
}Clone)]
20pub struct DiagSymbolList<S = Symbol>(Vec<S>);
21
22impl<S> From<Vec<S>> for DiagSymbolList<S> {
23    fn from(v: Vec<S>) -> Self {
24        DiagSymbolList(v)
25    }
26}
27
28impl<S> FromIterator<S> for DiagSymbolList<S> {
29    fn from_iter<T: IntoIterator<Item = S>>(iter: T) -> Self {
30        iter.into_iter().collect::<Vec<_>>().into()
31    }
32}
33
34impl<S: std::fmt::Display> IntoDiagArg for DiagSymbolList<S> {
35    fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
36        DiagArgValue::StrListSepByAnd(
37            self.0.into_iter().map(|sym| Cow::Owned(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`{0}`", sym))
    })format!("`{sym}`"))).collect(),
38        )
39    }
40}
41
42impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetDataLayoutErrors<'_> {
43    fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
44        match self {
45            TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
46                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("invalid address space `{$addr_space}` for `{$cause}` in \"data-layout\": {$err}"))inline_fluent!("invalid address space `{$addr_space}` for `{$cause}` in \"data-layout\": {$err}"))
47                    .with_arg("addr_space", addr_space)
48                    .with_arg("cause", cause)
49                    .with_arg("err", err)
50            }
51            TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
52                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("invalid {$kind} `{$bit}` for `{$cause}` in \"data-layout\": {$err}"))inline_fluent!("invalid {$kind} `{$bit}` for `{$cause}` in \"data-layout\": {$err}"))
53                    .with_arg("kind", kind)
54                    .with_arg("bit", bit)
55                    .with_arg("cause", cause)
56                    .with_arg("err", err)
57            }
58            TargetDataLayoutErrors::MissingAlignment { cause } => {
59                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("missing alignment for `{$cause}` in \"data-layout\""))inline_fluent!("missing alignment for `{$cause}` in \"data-layout\""))
60                    .with_arg("cause", cause)
61            }
62            TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
63                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("invalid alignment for `{$cause}` in \"data-layout\": `{$align}` is {$err_kind ->
                    [not_power_of_two] not a power of 2
                    [too_large] too large
                    *[other] {\"\"}
                }"))inline_fluent!("invalid alignment for `{$cause}` in \"data-layout\": `{$align}` is {$err_kind ->
64                    [not_power_of_two] not a power of 2
65                    [too_large] too large
66                    *[other] {\"\"}
67                }"))
68                .with_arg("cause", cause)
69                .with_arg("err_kind", err.diag_ident())
70                .with_arg("align", err.align())
71            }
72            TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
73                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("inconsistent target specification: \"data-layout\" claims architecture is {$dl}-endian, while \"target-endian\" is `{$target}`"))inline_fluent!(
74                    "inconsistent target specification: \"data-layout\" claims architecture is {$dl}-endian, while \"target-endian\" is `{$target}`"
75                ))
76                .with_arg("dl", dl).with_arg("target", target)
77            }
78            TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
79                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("inconsistent target specification: \"data-layout\" claims pointers are {$pointer_size}-bit, while \"target-pointer-width\" is `{$target}`"))inline_fluent!(
80                    "inconsistent target specification: \"data-layout\" claims pointers are {$pointer_size}-bit, while \"target-pointer-width\" is `{$target}`"
81                )).with_arg("pointer_size", pointer_size).with_arg("target", target)
82            }
83            TargetDataLayoutErrors::InvalidBitsSize { err } => {
84                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("{$err}"))inline_fluent!("{$err}")).with_arg("err", err)
85            }
86            TargetDataLayoutErrors::UnknownPointerSpecification { err } => {
87                Diag::new(dcx, level, rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("unknown pointer specification `{$err}` in datalayout string"))inline_fluent!("unknown pointer specification `{$err}` in datalayout string"))
88                    .with_arg("err", err)
89            }
90        }
91    }
92}
93
94/// Utility struct used to apply a single label while highlighting multiple spans
95pub struct SingleLabelManySpans {
96    pub spans: Vec<Span>,
97    pub label: &'static str,
98}
99impl Subdiagnostic for SingleLabelManySpans {
100    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
101        diag.span_labels(self.spans, self.label);
102    }
103}
104
105#[derive(const _: () =
    {
        impl rustc_errors::Subdiagnostic for ExpectedLifetimeParameter {
            fn add_to_diag<__G>(self, diag: &mut rustc_errors::Diag<'_, __G>)
                where __G: rustc_errors::EmissionGuarantee {
                match self {
                    ExpectedLifetimeParameter {
                        span: __binding_0, count: __binding_1 } => {
                        diag.store_args();
                        diag.arg("count", __binding_1);
                        let __message =
                            diag.eagerly_translate(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("expected lifetime {$count ->\n        [1] parameter\n        *[other] parameters\n    }")));
                        diag.span_label(__binding_0, __message);
                        diag.restore_args();
                    }
                }
            }
        }
    };Subdiagnostic)]
106#[label(
107    "expected lifetime {$count ->
108        [1] parameter
109        *[other] parameters
110    }"
111)]
112pub struct ExpectedLifetimeParameter {
113    #[primary_span]
114    pub span: Span,
115    pub count: usize,
116}
117
118#[derive(const _: () =
    {
        impl rustc_errors::Subdiagnostic for IndicateAnonymousLifetime {
            fn add_to_diag<__G>(self, diag: &mut rustc_errors::Diag<'_, __G>)
                where __G: rustc_errors::EmissionGuarantee {
                match self {
                    IndicateAnonymousLifetime {
                        span: __binding_0,
                        count: __binding_1,
                        suggestion: __binding_2 } => {
                        let __code_0 =
                            [::alloc::__export::must_use({
                                                ::alloc::fmt::format(format_args!("{0}", __binding_2))
                                            })].into_iter();
                        diag.store_args();
                        diag.arg("count", __binding_1);
                        diag.arg("suggestion", __binding_2);
                        let __message =
                            diag.eagerly_translate(rustc_errors::DiagMessage::Inline(std::borrow::Cow::Borrowed("indicate the anonymous {$count ->\n        [1] lifetime\n        *[other] lifetimes\n    }")));
                        diag.span_suggestions_with_style(__binding_0, __message,
                            __code_0, rustc_errors::Applicability::Unspecified,
                            rustc_errors::SuggestionStyle::ShowAlways);
                        diag.restore_args();
                    }
                }
            }
        }
    };Subdiagnostic)]
119#[suggestion(
120    "indicate the anonymous {$count ->
121        [1] lifetime
122        *[other] lifetimes
123    }",
124    code = "{suggestion}",
125    style = "verbose"
126)]
127pub struct IndicateAnonymousLifetime {
128    #[primary_span]
129    pub span: Span,
130    pub count: usize,
131    pub suggestion: String,
132}
133
134#[derive(const _: () =
    {
        impl rustc_errors::Subdiagnostic for ElidedLifetimeInPathSubdiag {
            fn add_to_diag<__G>(self, diag: &mut rustc_errors::Diag<'_, __G>)
                where __G: rustc_errors::EmissionGuarantee {
                match self {
                    ElidedLifetimeInPathSubdiag {
                        expected: __binding_0, indicate: __binding_1 } => {
                        __binding_0.add_to_diag(diag);
                        if let Some(__binding_1) = __binding_1 {
                            __binding_1.add_to_diag(diag);
                        }
                        diag.store_args();
                        diag.restore_args();
                    }
                }
            }
        }
    };Subdiagnostic)]
135pub struct ElidedLifetimeInPathSubdiag {
136    #[subdiagnostic]
137    pub expected: ExpectedLifetimeParameter,
138    #[subdiagnostic]
139    pub indicate: Option<IndicateAnonymousLifetime>,
140}