use std::borrow::Cow; use rustc_abi::TargetDataLayoutErrors; use rustc_error_messages::{DiagArgValue, IntoDiagArg}; use rustc_macros::Subdiagnostic; use rustc_span::{Span, Symbol}; use crate::diagnostic::DiagLocation; use crate::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, Subdiagnostic, msg}; impl IntoDiagArg for DiagLocation { fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::Str(Cow::from(self.to_string())) } } #[derive(Clone)] pub struct DiagSymbolList(Vec); impl From> for DiagSymbolList { fn from(v: Vec) -> Self { DiagSymbolList(v) } } impl FromIterator for DiagSymbolList { fn from_iter>(iter: T) -> Self { iter.into_iter().collect::>().into() } } impl IntoDiagArg for DiagSymbolList { fn into_diag_arg(self, _: &mut Option) -> DiagArgValue { DiagArgValue::StrListSepByAnd( self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(), ) } } impl Diagnostic<'_, G> for TargetDataLayoutErrors<'_> { fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { match self { TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => { Diag::new(dcx, level, msg!("invalid address space `{$addr_space}` for `{$cause}` in \"data-layout\": {$err}")) .with_arg("addr_space", addr_space) .with_arg("cause", cause) .with_arg("err", err) } TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => { Diag::new(dcx, level, msg!("invalid {$kind} `{$bit}` for `{$cause}` in \"data-layout\": {$err}")) .with_arg("kind", kind) .with_arg("bit", bit) .with_arg("cause", cause) .with_arg("err", err) } TargetDataLayoutErrors::MissingAlignment { cause } => { Diag::new(dcx, level, msg!("missing alignment for `{$cause}` in \"data-layout\"")) .with_arg("cause", cause) } TargetDataLayoutErrors::InvalidAlignment { cause, err } => { Diag::new(dcx, level, msg!( "invalid alignment for `{$cause}` in \"data-layout\": {$err}" )) .with_arg("cause", cause) .with_arg("err", err.to_string()) } TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => { Diag::new(dcx, level, msg!( "inconsistent target specification: \"data-layout\" claims architecture is {$dl}-endian, while \"target-endian\" is `{$target}`" )) .with_arg("dl", dl).with_arg("target", target) } TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => { Diag::new(dcx, level, msg!( "inconsistent target specification: \"data-layout\" claims pointers are {$pointer_size}-bit, while \"target-pointer-width\" is `{$target}`" )).with_arg("pointer_size", pointer_size).with_arg("target", target) } TargetDataLayoutErrors::InvalidBitsSize { err } => { Diag::new(dcx, level, msg!("{$err}")).with_arg("err", err) } TargetDataLayoutErrors::UnknownPointerSpecification { err } => { Diag::new(dcx, level, msg!("unknown pointer specification `{$err}` in datalayout string")) .with_arg("err", err) } } } } /// Utility struct used to apply a single label while highlighting multiple spans pub struct SingleLabelManySpans { pub spans: Vec, pub label: &'static str, } impl Subdiagnostic for SingleLabelManySpans { fn add_to_diag(self, diag: &mut Diag<'_, G>) { diag.span_labels(self.spans, self.label); } } #[derive(Subdiagnostic)] #[label( "expected lifetime {$count -> [1] parameter *[other] parameters }" )] pub struct ExpectedLifetimeParameter { #[primary_span] pub span: Span, pub count: usize, } #[derive(Subdiagnostic)] #[suggestion( "indicate the anonymous {$count -> [1] lifetime *[other] lifetimes }", code = "{suggestion}", style = "verbose" )] pub struct IndicateAnonymousLifetime { #[primary_span] pub span: Span, pub count: usize, pub suggestion: String, } #[derive(Subdiagnostic)] pub struct ElidedLifetimeInPathSubdiag { #[subdiagnostic] pub expected: ExpectedLifetimeParameter, #[subdiagnostic] pub indicate: Option, }