2 fluent, DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg,
5 use rustc_ast_pretty::pprust;
7 use rustc_lint_defs::Level;
8 use rustc_span::edition::Edition;
9 use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
10 use rustc_target::abi::TargetDataLayoutErrors;
11 use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
15 use std::num::ParseIntError;
16 use std::path::{Path, PathBuf};
17 use std::process::ExitStatus;
19 pub struct DiagnosticArgFromDisplay<'a>(pub &'a dyn fmt::Display);
21 impl IntoDiagnosticArg for DiagnosticArgFromDisplay<'_> {
22 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
23 self.0.to_string().into_diagnostic_arg()
27 impl<'a> From<&'a dyn fmt::Display> for DiagnosticArgFromDisplay<'a> {
28 fn from(t: &'a dyn fmt::Display) -> Self {
29 DiagnosticArgFromDisplay(t)
33 impl<'a, T: fmt::Display> From<&'a T> for DiagnosticArgFromDisplay<'a> {
34 fn from(t: &'a T) -> Self {
35 DiagnosticArgFromDisplay(t)
39 macro_rules! into_diagnostic_arg_using_display {
40 ($( $ty:ty ),+ $(,)?) => {
42 impl IntoDiagnosticArg for $ty {
43 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
44 self.to_string().into_diagnostic_arg()
51 into_diagnostic_arg_using_display!(
63 std::boxed::Box<dyn std::error::Error>,
68 MacroRulesNormalizedIdent,
76 impl IntoDiagnosticArg for bool {
77 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
79 DiagnosticArgValue::Str(Cow::Borrowed("true"))
81 DiagnosticArgValue::Str(Cow::Borrowed("false"))
86 impl IntoDiagnosticArg for char {
87 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
88 DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self)))
92 impl IntoDiagnosticArg for Symbol {
93 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
94 self.to_ident_string().into_diagnostic_arg()
98 impl<'a> IntoDiagnosticArg for &'a str {
99 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
100 self.to_string().into_diagnostic_arg()
104 impl IntoDiagnosticArg for String {
105 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
106 DiagnosticArgValue::Str(Cow::Owned(self))
110 impl<'a> IntoDiagnosticArg for Cow<'a, str> {
111 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
112 DiagnosticArgValue::Str(Cow::Owned(self.into_owned()))
116 impl<'a> IntoDiagnosticArg for &'a Path {
117 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
118 DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
122 impl IntoDiagnosticArg for PathBuf {
123 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
124 DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
128 impl IntoDiagnosticArg for usize {
129 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
130 DiagnosticArgValue::Number(self)
134 impl IntoDiagnosticArg for PanicStrategy {
135 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
136 DiagnosticArgValue::Str(Cow::Owned(self.desc().to_string()))
140 impl IntoDiagnosticArg for hir::ConstContext {
141 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
142 DiagnosticArgValue::Str(Cow::Borrowed(match self {
143 hir::ConstContext::ConstFn => "constant function",
144 hir::ConstContext::Static(_) => "static",
145 hir::ConstContext::Const => "constant",
150 impl IntoDiagnosticArg for ast::Path {
151 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
152 DiagnosticArgValue::Str(Cow::Owned(pprust::path_to_string(&self)))
156 impl IntoDiagnosticArg for ast::token::Token {
157 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
158 DiagnosticArgValue::Str(pprust::token_to_string(&self))
162 impl IntoDiagnosticArg for ast::token::TokenKind {
163 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
164 DiagnosticArgValue::Str(pprust::token_kind_to_string(&self))
168 impl IntoDiagnosticArg for Level {
169 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
170 DiagnosticArgValue::Str(Cow::Borrowed(match self {
171 Level::Allow => "-A",
173 Level::ForceWarn(_) => "--force-warn",
175 Level::Forbid => "-F",
176 Level::Expect(_) => {
177 unreachable!("lints with the level of `expect` should not run this code");
184 pub struct DiagnosticSymbolList(Vec<Symbol>);
186 impl From<Vec<Symbol>> for DiagnosticSymbolList {
187 fn from(v: Vec<Symbol>) -> Self {
188 DiagnosticSymbolList(v)
192 impl IntoDiagnosticArg for DiagnosticSymbolList {
193 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
194 // FIXME: replace the logic here with a real list formatter
195 let symbols = match &self.0[..] {
196 [symbol] => format!("`{symbol}`"),
198 format!("`{symbol}` and `{last}`",)
200 [symbols @ .., last] => {
201 let mut result = String::new();
202 for symbol in symbols {
203 write!(result, "`{symbol}`, ").unwrap();
205 write!(result, "and `{last}`").unwrap();
208 [] => unreachable!(),
210 DiagnosticArgValue::Str(Cow::Owned(symbols))
214 impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
215 fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> {
218 TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
219 diag = handler.struct_fatal(fluent::errors_target_invalid_address_space);
220 diag.set_arg("addr_space", addr_space);
221 diag.set_arg("cause", cause);
222 diag.set_arg("err", err);
225 TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
226 diag = handler.struct_fatal(fluent::errors_target_invalid_bits);
227 diag.set_arg("kind", kind);
228 diag.set_arg("bit", bit);
229 diag.set_arg("cause", cause);
230 diag.set_arg("err", err);
233 TargetDataLayoutErrors::MissingAlignment { cause } => {
234 diag = handler.struct_fatal(fluent::errors_target_missing_alignment);
235 diag.set_arg("cause", cause);
238 TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
239 diag = handler.struct_fatal(fluent::errors_target_invalid_alignment);
240 diag.set_arg("cause", cause);
241 diag.set_arg("err", err);
244 TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
245 diag = handler.struct_fatal(fluent::errors_target_inconsistent_architecture);
246 diag.set_arg("dl", dl);
247 diag.set_arg("target", target);
250 TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
251 diag = handler.struct_fatal(fluent::errors_target_inconsistent_pointer_width);
252 diag.set_arg("pointer_size", pointer_size);
253 diag.set_arg("target", target);
256 TargetDataLayoutErrors::InvalidBitsSize { err } => {
257 diag = handler.struct_fatal(fluent::errors_target_invalid_bits_size);
258 diag.set_arg("err", err);