2023-07-03 09:08:49 +00:00
|
|
|
use crate::diagnostic::DiagnosticLocation;
|
2023-04-08 19:37:41 +00:00
|
|
|
use crate::{fluent_generated as fluent, AddToDiagnostic};
|
2023-12-18 03:12:39 +00:00
|
|
|
use crate::{
|
|
|
|
DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
|
|
|
|
IntoDiagnosticArg, Level,
|
|
|
|
};
|
2022-10-12 20:55:28 +00:00
|
|
|
use rustc_ast as ast;
|
|
|
|
use rustc_ast_pretty::pprust;
|
|
|
|
use rustc_hir as hir;
|
|
|
|
use rustc_span::edition::Edition;
|
|
|
|
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
|
2023-04-08 19:37:41 +00:00
|
|
|
use rustc_span::Span;
|
2022-10-14 12:25:12 +00:00
|
|
|
use rustc_target::abi::TargetDataLayoutErrors;
|
|
|
|
use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
|
2022-11-17 13:53:14 +00:00
|
|
|
use rustc_type_ir as type_ir;
|
2023-07-03 09:08:49 +00:00
|
|
|
use std::backtrace::Backtrace;
|
2022-10-12 20:55:28 +00:00
|
|
|
use std::borrow::Cow;
|
|
|
|
use std::fmt;
|
|
|
|
use std::num::ParseIntError;
|
|
|
|
use std::path::{Path, PathBuf};
|
2022-10-30 19:38:37 +00:00
|
|
|
use std::process::ExitStatus;
|
2022-10-12 20:55:28 +00:00
|
|
|
|
|
|
|
pub struct DiagnosticArgFromDisplay<'a>(pub &'a dyn fmt::Display);
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for DiagnosticArgFromDisplay<'_> {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
self.0.to_string().into_diagnostic_arg()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> From<&'a dyn fmt::Display> for DiagnosticArgFromDisplay<'a> {
|
|
|
|
fn from(t: &'a dyn fmt::Display) -> Self {
|
|
|
|
DiagnosticArgFromDisplay(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, T: fmt::Display> From<&'a T> for DiagnosticArgFromDisplay<'a> {
|
|
|
|
fn from(t: &'a T) -> Self {
|
|
|
|
DiagnosticArgFromDisplay(t)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-30 16:00:20 +00:00
|
|
|
impl<'a, T: Clone + IntoDiagnosticArg> IntoDiagnosticArg for &'a T {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
self.clone().into_diagnostic_arg()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-12 20:55:28 +00:00
|
|
|
macro_rules! into_diagnostic_arg_using_display {
|
|
|
|
($( $ty:ty ),+ $(,)?) => {
|
|
|
|
$(
|
|
|
|
impl IntoDiagnosticArg for $ty {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
self.to_string().into_diagnostic_arg()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)+
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
into_diagnostic_arg_using_display!(
|
2023-02-25 13:53:42 +00:00
|
|
|
ast::ParamKindOrd,
|
2022-10-12 20:55:28 +00:00
|
|
|
i8,
|
|
|
|
u8,
|
|
|
|
i16,
|
|
|
|
u16,
|
|
|
|
u32,
|
|
|
|
i64,
|
|
|
|
i128,
|
|
|
|
u128,
|
|
|
|
std::io::Error,
|
2022-08-09 00:14:43 +00:00
|
|
|
Box<dyn std::error::Error>,
|
2022-10-12 20:55:28 +00:00
|
|
|
std::num::NonZeroU32,
|
|
|
|
hir::Target,
|
|
|
|
Edition,
|
|
|
|
Ident,
|
|
|
|
MacroRulesNormalizedIdent,
|
|
|
|
ParseIntError,
|
|
|
|
StackProtector,
|
|
|
|
&TargetTriple,
|
2022-10-30 19:38:37 +00:00
|
|
|
SplitDebuginfo,
|
|
|
|
ExitStatus,
|
2022-10-12 20:55:28 +00:00
|
|
|
);
|
|
|
|
|
2023-05-17 10:30:14 +00:00
|
|
|
impl IntoDiagnosticArg for i32 {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Number(self.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for u64 {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Number(self.into())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-12 20:55:28 +00:00
|
|
|
impl IntoDiagnosticArg for bool {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
if self {
|
|
|
|
DiagnosticArgValue::Str(Cow::Borrowed("true"))
|
|
|
|
} else {
|
|
|
|
DiagnosticArgValue::Str(Cow::Borrowed("false"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for char {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
2023-07-24 04:08:09 +00:00
|
|
|
DiagnosticArgValue::Str(Cow::Owned(format!("{self:?}")))
|
2022-10-12 20:55:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for Symbol {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
self.to_ident_string().into_diagnostic_arg()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> IntoDiagnosticArg for &'a str {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
self.to_string().into_diagnostic_arg()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for String {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::Owned(self))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-26 17:01:22 +00:00
|
|
|
impl<'a> IntoDiagnosticArg for Cow<'a, str> {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::Owned(self.into_owned()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-12 20:55:28 +00:00
|
|
|
impl<'a> IntoDiagnosticArg for &'a Path {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for PathBuf {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for usize {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
2023-05-17 10:30:14 +00:00
|
|
|
DiagnosticArgValue::Number(self as i128)
|
2022-10-12 20:55:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for PanicStrategy {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::Owned(self.desc().to_string()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for hir::ConstContext {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::Borrowed(match self {
|
2023-05-17 10:30:14 +00:00
|
|
|
hir::ConstContext::ConstFn => "const_fn",
|
2022-10-12 20:55:28 +00:00
|
|
|
hir::ConstContext::Static(_) => "static",
|
2023-09-18 15:30:07 +00:00
|
|
|
hir::ConstContext::Const { .. } => "const",
|
2022-10-12 20:55:28 +00:00
|
|
|
}))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-25 10:12:52 +00:00
|
|
|
impl IntoDiagnosticArg for ast::Expr {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::Owned(pprust::expr_to_string(&self)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-12 20:55:28 +00:00
|
|
|
impl IntoDiagnosticArg for ast::Path {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::Owned(pprust::path_to_string(&self)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for ast::token::Token {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(pprust::token_to_string(&self))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for ast::token::TokenKind {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(pprust::token_kind_to_string(&self))
|
|
|
|
}
|
|
|
|
}
|
2022-10-05 00:56:05 +00:00
|
|
|
|
2022-11-17 13:53:14 +00:00
|
|
|
impl IntoDiagnosticArg for type_ir::FloatTy {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::Borrowed(self.name_str()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-19 13:48:15 +00:00
|
|
|
impl IntoDiagnosticArg for std::ffi::CString {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for rustc_data_structures::small_c_str::SmallCStr {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-05 20:05:45 +00:00
|
|
|
impl IntoDiagnosticArg for ast::Visibility {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
let s = pprust::vis_to_string(&self);
|
|
|
|
let s = s.trim_end().to_string();
|
|
|
|
DiagnosticArgValue::Str(Cow::Owned(s))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-18 03:12:39 +00:00
|
|
|
impl IntoDiagnosticArg for rustc_lint_defs::Level {
|
2022-10-14 12:25:12 +00:00
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
2023-01-10 07:56:17 +00:00
|
|
|
DiagnosticArgValue::Str(Cow::Borrowed(self.to_cmd_flag()))
|
2022-10-14 12:25:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-22 10:48:20 +00:00
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct DiagnosticSymbolList(Vec<Symbol>);
|
|
|
|
|
|
|
|
impl From<Vec<Symbol>> for DiagnosticSymbolList {
|
|
|
|
fn from(v: Vec<Symbol>) -> Self {
|
|
|
|
DiagnosticSymbolList(v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for DiagnosticSymbolList {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
2022-11-06 06:43:25 +00:00
|
|
|
DiagnosticArgValue::StrListSepByAnd(
|
|
|
|
self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(),
|
|
|
|
)
|
2022-10-22 10:48:20 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-05 05:04:38 +00:00
|
|
|
impl<Id> IntoDiagnosticArg for hir::def::Res<Id> {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-18 03:12:39 +00:00
|
|
|
impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for TargetDataLayoutErrors<'_> {
|
|
|
|
fn into_diagnostic(self, dcx: &DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> {
|
2022-10-05 00:56:05 +00:00
|
|
|
match self {
|
|
|
|
TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
|
2024-01-03 05:00:29 +00:00
|
|
|
DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_address_space)
|
|
|
|
.arg_mv("addr_space", addr_space)
|
|
|
|
.arg_mv("cause", cause)
|
|
|
|
.arg_mv("err", err)
|
2022-10-05 00:56:05 +00:00
|
|
|
}
|
|
|
|
TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
|
2024-01-03 05:00:29 +00:00
|
|
|
DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_bits)
|
|
|
|
.arg_mv("kind", kind)
|
|
|
|
.arg_mv("bit", bit)
|
|
|
|
.arg_mv("cause", cause)
|
|
|
|
.arg_mv("err", err)
|
2022-10-05 00:56:05 +00:00
|
|
|
}
|
|
|
|
TargetDataLayoutErrors::MissingAlignment { cause } => {
|
2024-01-03 05:00:29 +00:00
|
|
|
DiagnosticBuilder::new(dcx, level, fluent::errors_target_missing_alignment)
|
|
|
|
.arg_mv("cause", cause)
|
2022-10-05 00:56:05 +00:00
|
|
|
}
|
|
|
|
TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
|
2024-01-03 05:00:29 +00:00
|
|
|
DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_alignment)
|
|
|
|
.arg_mv("cause", cause)
|
|
|
|
.arg_mv("err_kind", err.diag_ident())
|
|
|
|
.arg_mv("align", err.align())
|
2022-10-05 00:56:05 +00:00
|
|
|
}
|
|
|
|
TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
|
2024-01-03 05:00:29 +00:00
|
|
|
DiagnosticBuilder::new(dcx, level, fluent::errors_target_inconsistent_architecture)
|
|
|
|
.arg_mv("dl", dl)
|
|
|
|
.arg_mv("target", target)
|
2022-10-05 00:56:05 +00:00
|
|
|
}
|
|
|
|
TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
|
2024-01-03 05:00:29 +00:00
|
|
|
DiagnosticBuilder::new(dcx, level, fluent::errors_target_inconsistent_pointer_width)
|
|
|
|
.arg_mv("pointer_size", pointer_size)
|
|
|
|
.arg_mv("target", target)
|
2022-10-05 00:56:05 +00:00
|
|
|
}
|
|
|
|
TargetDataLayoutErrors::InvalidBitsSize { err } => {
|
2024-01-03 05:00:29 +00:00
|
|
|
DiagnosticBuilder::new(dcx, level, fluent::errors_target_invalid_bits_size)
|
|
|
|
.arg_mv("err", err)
|
2022-10-05 00:56:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-04-08 19:37:41 +00:00
|
|
|
|
|
|
|
/// Utility struct used to apply a single label while highlighting multiple spans
|
|
|
|
pub struct SingleLabelManySpans {
|
|
|
|
pub spans: Vec<Span>,
|
|
|
|
pub label: &'static str,
|
|
|
|
}
|
|
|
|
impl AddToDiagnostic for SingleLabelManySpans {
|
|
|
|
fn add_to_diagnostic_with<F>(self, diag: &mut crate::Diagnostic, _: F) {
|
2023-12-20 23:42:00 +00:00
|
|
|
diag.span_labels(self.spans, self.label);
|
2023-04-08 19:37:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-03 09:08:49 +00:00
|
|
|
#[derive(Subdiagnostic)]
|
|
|
|
#[label(errors_expected_lifetime_parameter)]
|
|
|
|
pub struct ExpectedLifetimeParameter {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
pub count: usize,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Subdiagnostic)]
|
|
|
|
#[note(errors_delayed_at_with_newline)]
|
|
|
|
pub struct DelayedAtWithNewline {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
pub emitted_at: DiagnosticLocation,
|
|
|
|
pub note: Backtrace,
|
|
|
|
}
|
|
|
|
#[derive(Subdiagnostic)]
|
|
|
|
#[note(errors_delayed_at_without_newline)]
|
|
|
|
pub struct DelayedAtWithoutNewline {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
|
|
|
pub emitted_at: DiagnosticLocation,
|
|
|
|
pub note: Backtrace,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for DiagnosticLocation {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::from(self.to_string()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl IntoDiagnosticArg for Backtrace {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::from(self.to_string()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Subdiagnostic)]
|
|
|
|
#[note(errors_invalid_flushed_delayed_diagnostic_level)]
|
|
|
|
pub struct InvalidFlushedDelayedDiagnosticLevel {
|
|
|
|
#[primary_span]
|
|
|
|
pub span: Span,
|
2023-12-18 03:12:39 +00:00
|
|
|
pub level: Level,
|
2023-07-03 09:08:49 +00:00
|
|
|
}
|
2023-12-18 03:12:39 +00:00
|
|
|
impl IntoDiagnosticArg for Level {
|
2023-07-03 09:08:49 +00:00
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(Cow::from(self.to_string()))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-07-17 06:00:13 +00:00
|
|
|
#[derive(Subdiagnostic)]
|
|
|
|
#[suggestion(errors_indicate_anonymous_lifetime, code = "{suggestion}", style = "verbose")]
|
2023-07-03 09:08:49 +00:00
|
|
|
pub struct IndicateAnonymousLifetime {
|
2023-07-17 06:00:13 +00:00
|
|
|
#[primary_span]
|
2023-07-03 09:08:49 +00:00
|
|
|
pub span: Span,
|
|
|
|
pub count: usize,
|
|
|
|
pub suggestion: String,
|
|
|
|
}
|
2023-12-12 18:54:49 +00:00
|
|
|
|
|
|
|
impl IntoDiagnosticArg for type_ir::ClosureKind {
|
|
|
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
|
|
|
DiagnosticArgValue::Str(self.as_str().into())
|
|
|
|
}
|
|
|
|
}
|