rust/compiler/rustc_errors/src/diagnostic_impls.rs
2023-01-10 10:56:17 +03:00

259 lines
7.9 KiB
Rust

use crate::{
fluent, DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg,
};
use rustc_ast as ast;
use rustc_ast_pretty::pprust;
use rustc_hir as hir;
use rustc_lint_defs::Level;
use rustc_span::edition::Edition;
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
use rustc_target::abi::TargetDataLayoutErrors;
use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
use rustc_type_ir as type_ir;
use std::borrow::Cow;
use std::fmt;
use std::num::ParseIntError;
use std::path::{Path, PathBuf};
use std::process::ExitStatus;
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)
}
}
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!(
i8,
u8,
i16,
u16,
i32,
u32,
i64,
u64,
i128,
u128,
std::io::Error,
Box<dyn std::error::Error>,
std::num::NonZeroU32,
hir::Target,
Edition,
Ident,
MacroRulesNormalizedIdent,
ParseIntError,
StackProtector,
&TargetTriple,
SplitDebuginfo,
ExitStatus,
);
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> {
DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self)))
}
}
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))
}
}
impl<'a> IntoDiagnosticArg for Cow<'a, str> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
DiagnosticArgValue::Str(Cow::Owned(self.into_owned()))
}
}
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> {
DiagnosticArgValue::Number(self)
}
}
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 {
hir::ConstContext::ConstFn => "constant function",
hir::ConstContext::Static(_) => "static",
hir::ConstContext::Const => "constant",
}))
}
}
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::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))
}
}
impl IntoDiagnosticArg for type_ir::FloatTy {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
DiagnosticArgValue::Str(Cow::Borrowed(self.name_str()))
}
}
impl IntoDiagnosticArg for Level {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
DiagnosticArgValue::Str(Cow::Borrowed(self.to_cmd_flag()))
}
}
#[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> {
DiagnosticArgValue::StrListSepByAnd(
self.0.into_iter().map(|sym| Cow::Owned(format!("`{sym}`"))).collect(),
)
}
}
impl<Id> IntoDiagnosticArg for hir::def::Res<Id> {
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
DiagnosticArgValue::Str(Cow::Borrowed(self.descr()))
}
}
impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> {
let mut diag;
match self {
TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
diag = handler.struct_fatal(fluent::errors_target_invalid_address_space);
diag.set_arg("addr_space", addr_space);
diag.set_arg("cause", cause);
diag.set_arg("err", err);
diag
}
TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
diag = handler.struct_fatal(fluent::errors_target_invalid_bits);
diag.set_arg("kind", kind);
diag.set_arg("bit", bit);
diag.set_arg("cause", cause);
diag.set_arg("err", err);
diag
}
TargetDataLayoutErrors::MissingAlignment { cause } => {
diag = handler.struct_fatal(fluent::errors_target_missing_alignment);
diag.set_arg("cause", cause);
diag
}
TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
diag = handler.struct_fatal(fluent::errors_target_invalid_alignment);
diag.set_arg("cause", cause);
diag.set_arg("err", err);
diag
}
TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
diag = handler.struct_fatal(fluent::errors_target_inconsistent_architecture);
diag.set_arg("dl", dl);
diag.set_arg("target", target);
diag
}
TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
diag = handler.struct_fatal(fluent::errors_target_inconsistent_pointer_width);
diag.set_arg("pointer_size", pointer_size);
diag.set_arg("target", target);
diag
}
TargetDataLayoutErrors::InvalidBitsSize { err } => {
diag = handler.struct_fatal(fluent::errors_target_invalid_bits_size);
diag.set_arg("err", err);
diag
}
}
}
}