rustc_errors/
diagnostic_impls.rs1use 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,
11 fluent_generated as fluent,
12};
13
14impl IntoDiagArg for DiagLocation {
15 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
16 DiagArgValue::Str(Cow::from(self.to_string()))
17 }
18}
19
20#[derive(Clone)]
21pub struct DiagSymbolList<S = Symbol>(Vec<S>);
22
23impl<S> From<Vec<S>> for DiagSymbolList<S> {
24 fn from(v: Vec<S>) -> Self {
25 DiagSymbolList(v)
26 }
27}
28
29impl<S> FromIterator<S> for DiagSymbolList<S> {
30 fn from_iter<T: IntoIterator<Item = S>>(iter: T) -> Self {
31 iter.into_iter().collect::<Vec<_>>().into()
32 }
33}
34
35impl<S: std::fmt::Display> IntoDiagArg for DiagSymbolList<S> {
36 fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
37 DiagArgValue::StrListSepByAnd(
38 self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(),
39 )
40 }
41}
42
43impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetDataLayoutErrors<'_> {
44 fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
45 match self {
46 TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
47 Diag::new(dcx, level, fluent::errors_target_invalid_address_space)
48 .with_arg("addr_space", addr_space)
49 .with_arg("cause", cause)
50 .with_arg("err", err)
51 }
52 TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
53 Diag::new(dcx, level, fluent::errors_target_invalid_bits)
54 .with_arg("kind", kind)
55 .with_arg("bit", bit)
56 .with_arg("cause", cause)
57 .with_arg("err", err)
58 }
59 TargetDataLayoutErrors::MissingAlignment { cause } => {
60 Diag::new(dcx, level, fluent::errors_target_missing_alignment)
61 .with_arg("cause", cause)
62 }
63 TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
64 Diag::new(dcx, level, fluent::errors_target_invalid_alignment)
65 .with_arg("cause", cause)
66 .with_arg("err_kind", err.diag_ident())
67 .with_arg("align", err.align())
68 }
69 TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
70 Diag::new(dcx, level, fluent::errors_target_inconsistent_architecture)
71 .with_arg("dl", dl)
72 .with_arg("target", target)
73 }
74 TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
75 Diag::new(dcx, level, fluent::errors_target_inconsistent_pointer_width)
76 .with_arg("pointer_size", pointer_size)
77 .with_arg("target", target)
78 }
79 TargetDataLayoutErrors::InvalidBitsSize { err } => {
80 Diag::new(dcx, level, fluent::errors_target_invalid_bits_size).with_arg("err", err)
81 }
82 TargetDataLayoutErrors::UnknownPointerSpecification { err } => {
83 Diag::new(dcx, level, fluent::errors_target_invalid_datalayout_pointer_spec)
84 .with_arg("err", err)
85 }
86 }
87 }
88}
89
90pub struct SingleLabelManySpans {
92 pub spans: Vec<Span>,
93 pub label: &'static str,
94}
95impl Subdiagnostic for SingleLabelManySpans {
96 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
97 diag.span_labels(self.spans, self.label);
98 }
99}
100
101#[derive(Subdiagnostic)]
102#[label(errors_expected_lifetime_parameter)]
103pub struct ExpectedLifetimeParameter {
104 #[primary_span]
105 pub span: Span,
106 pub count: usize,
107}
108
109#[derive(Subdiagnostic)]
110#[suggestion(errors_indicate_anonymous_lifetime, code = "{suggestion}", style = "verbose")]
111pub struct IndicateAnonymousLifetime {
112 #[primary_span]
113 pub span: Span,
114 pub count: usize,
115 pub suggestion: String,
116}
117
118#[derive(Subdiagnostic)]
119pub struct ElidedLifetimeInPathSubdiag {
120 #[subdiagnostic]
121 pub expected: ExpectedLifetimeParameter,
122 #[subdiagnostic]
123 pub indicate: Option<IndicateAnonymousLifetime>,
124}