mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 13:04:42 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			381 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			381 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use crate::diagnostic::DiagnosticLocation;
 | |
| use crate::{fluent_generated as fluent, AddToDiagnostic};
 | |
| use crate::{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_span::Span;
 | |
| use rustc_target::abi::TargetDataLayoutErrors;
 | |
| use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
 | |
| use rustc_type_ir as type_ir;
 | |
| use std::backtrace::Backtrace;
 | |
| 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)
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl<'a, T: Clone + IntoDiagnosticArg> IntoDiagnosticArg for &'a T {
 | |
|     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
 | |
|         self.clone().into_diagnostic_arg()
 | |
|     }
 | |
| }
 | |
| 
 | |
| 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!(
 | |
|     ast::ParamKindOrd,
 | |
|     i8,
 | |
|     u8,
 | |
|     i16,
 | |
|     u16,
 | |
|     u32,
 | |
|     i64,
 | |
|     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 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())
 | |
|     }
 | |
| }
 | |
| 
 | |
| 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 as i128)
 | |
|     }
 | |
| }
 | |
| 
 | |
| 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 => "const_fn",
 | |
|             hir::ConstContext::Static(_) => "static",
 | |
|             hir::ConstContext::Const { .. } => "const",
 | |
|         }))
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl IntoDiagnosticArg for ast::Expr {
 | |
|     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
 | |
|         DiagnosticArgValue::Str(Cow::Owned(pprust::expr_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 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()))
 | |
|     }
 | |
| }
 | |
| 
 | |
| 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))
 | |
|     }
 | |
| }
 | |
| 
 | |
| 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_kind", err.diag_ident());
 | |
|                 diag.set_arg("align", err.align());
 | |
|                 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
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// Utility struct used to apply a single label while highlighting multiple spans
 | |
| pub struct SingleLabelManySpans {
 | |
|     pub spans: Vec<Span>,
 | |
|     pub label: &'static str,
 | |
|     pub kind: LabelKind,
 | |
| }
 | |
| impl AddToDiagnostic for SingleLabelManySpans {
 | |
|     fn add_to_diagnostic_with<F>(self, diag: &mut crate::Diagnostic, _: F) {
 | |
|         match self.kind {
 | |
|             LabelKind::Note => diag.span_note(self.spans, self.label),
 | |
|             LabelKind::Label => diag.span_labels(self.spans, self.label),
 | |
|             LabelKind::Help => diag.span_help(self.spans, self.label),
 | |
|         };
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// The kind of label to attach when using [`SingleLabelManySpans`]
 | |
| pub enum LabelKind {
 | |
|     Note,
 | |
|     Label,
 | |
|     Help,
 | |
| }
 | |
| 
 | |
| #[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,
 | |
|     pub level: rustc_errors::Level,
 | |
| }
 | |
| impl IntoDiagnosticArg for rustc_errors::Level {
 | |
|     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
 | |
|         DiagnosticArgValue::Str(Cow::from(self.to_string()))
 | |
|     }
 | |
| }
 | |
| 
 | |
| #[derive(Subdiagnostic)]
 | |
| #[suggestion(errors_indicate_anonymous_lifetime, code = "{suggestion}", style = "verbose")]
 | |
| pub struct IndicateAnonymousLifetime {
 | |
|     #[primary_span]
 | |
|     pub span: Span,
 | |
|     pub count: usize,
 | |
|     pub suggestion: String,
 | |
| }
 | 
