]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_errors/src/diagnostic_impls.rs
Rollup merge of #103560 - zbyrn:issue-103358-fix, r=cjgillot
[rust.git] / compiler / rustc_errors / src / diagnostic_impls.rs
1 use crate::{
2     fluent, DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg,
3 };
4 use rustc_ast as ast;
5 use rustc_ast_pretty::pprust;
6 use rustc_hir as hir;
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};
12 use std::borrow::Cow;
13 use std::fmt;
14 use std::num::ParseIntError;
15 use std::path::{Path, PathBuf};
16
17 pub struct DiagnosticArgFromDisplay<'a>(pub &'a dyn fmt::Display);
18
19 impl IntoDiagnosticArg for DiagnosticArgFromDisplay<'_> {
20     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
21         self.0.to_string().into_diagnostic_arg()
22     }
23 }
24
25 impl<'a> From<&'a dyn fmt::Display> for DiagnosticArgFromDisplay<'a> {
26     fn from(t: &'a dyn fmt::Display) -> Self {
27         DiagnosticArgFromDisplay(t)
28     }
29 }
30
31 impl<'a, T: fmt::Display> From<&'a T> for DiagnosticArgFromDisplay<'a> {
32     fn from(t: &'a T) -> Self {
33         DiagnosticArgFromDisplay(t)
34     }
35 }
36
37 macro_rules! into_diagnostic_arg_using_display {
38     ($( $ty:ty ),+ $(,)?) => {
39         $(
40             impl IntoDiagnosticArg for $ty {
41                 fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
42                     self.to_string().into_diagnostic_arg()
43                 }
44             }
45         )+
46     }
47 }
48
49 into_diagnostic_arg_using_display!(
50     i8,
51     u8,
52     i16,
53     u16,
54     i32,
55     u32,
56     i64,
57     u64,
58     i128,
59     u128,
60     std::io::Error,
61     std::num::NonZeroU32,
62     hir::Target,
63     Edition,
64     Ident,
65     MacroRulesNormalizedIdent,
66     ParseIntError,
67     StackProtector,
68     &TargetTriple,
69     SplitDebuginfo
70 );
71
72 impl IntoDiagnosticArg for bool {
73     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
74         if self {
75             DiagnosticArgValue::Str(Cow::Borrowed("true"))
76         } else {
77             DiagnosticArgValue::Str(Cow::Borrowed("false"))
78         }
79     }
80 }
81
82 impl IntoDiagnosticArg for char {
83     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
84         DiagnosticArgValue::Str(Cow::Owned(format!("{:?}", self)))
85     }
86 }
87
88 impl IntoDiagnosticArg for Symbol {
89     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
90         self.to_ident_string().into_diagnostic_arg()
91     }
92 }
93
94 impl<'a> IntoDiagnosticArg for &'a str {
95     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
96         self.to_string().into_diagnostic_arg()
97     }
98 }
99
100 impl IntoDiagnosticArg for String {
101     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
102         DiagnosticArgValue::Str(Cow::Owned(self))
103     }
104 }
105
106 impl<'a> IntoDiagnosticArg for &'a Path {
107     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
108         DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
109     }
110 }
111
112 impl IntoDiagnosticArg for PathBuf {
113     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
114         DiagnosticArgValue::Str(Cow::Owned(self.display().to_string()))
115     }
116 }
117
118 impl IntoDiagnosticArg for usize {
119     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
120         DiagnosticArgValue::Number(self)
121     }
122 }
123
124 impl IntoDiagnosticArg for PanicStrategy {
125     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
126         DiagnosticArgValue::Str(Cow::Owned(self.desc().to_string()))
127     }
128 }
129
130 impl IntoDiagnosticArg for hir::ConstContext {
131     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
132         DiagnosticArgValue::Str(Cow::Borrowed(match self {
133             hir::ConstContext::ConstFn => "constant function",
134             hir::ConstContext::Static(_) => "static",
135             hir::ConstContext::Const => "constant",
136         }))
137     }
138 }
139
140 impl IntoDiagnosticArg for ast::Path {
141     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
142         DiagnosticArgValue::Str(Cow::Owned(pprust::path_to_string(&self)))
143     }
144 }
145
146 impl IntoDiagnosticArg for ast::token::Token {
147     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
148         DiagnosticArgValue::Str(pprust::token_to_string(&self))
149     }
150 }
151
152 impl IntoDiagnosticArg for ast::token::TokenKind {
153     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
154         DiagnosticArgValue::Str(pprust::token_kind_to_string(&self))
155     }
156 }
157
158 impl IntoDiagnosticArg for Level {
159     fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
160         DiagnosticArgValue::Str(Cow::Borrowed(match self {
161             Level::Allow => "-A",
162             Level::Warn => "-W",
163             Level::ForceWarn(_) => "--force-warn",
164             Level::Deny => "-D",
165             Level::Forbid => "-F",
166             Level::Expect(_) => {
167                 unreachable!("lints with the level of `expect` should not run this code");
168             }
169         }))
170     }
171 }
172
173 impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
174     fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> {
175         let mut diag;
176         match self {
177             TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
178                 diag = handler.struct_fatal(fluent::errors_target_invalid_address_space);
179                 diag.set_arg("addr_space", addr_space);
180                 diag.set_arg("cause", cause);
181                 diag.set_arg("err", err);
182                 diag
183             }
184             TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
185                 diag = handler.struct_fatal(fluent::errors_target_invalid_bits);
186                 diag.set_arg("kind", kind);
187                 diag.set_arg("bit", bit);
188                 diag.set_arg("cause", cause);
189                 diag.set_arg("err", err);
190                 diag
191             }
192             TargetDataLayoutErrors::MissingAlignment { cause } => {
193                 diag = handler.struct_fatal(fluent::errors_target_missing_alignment);
194                 diag.set_arg("cause", cause);
195                 diag
196             }
197             TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
198                 diag = handler.struct_fatal(fluent::errors_target_invalid_alignment);
199                 diag.set_arg("cause", cause);
200                 diag.set_arg("err", err);
201                 diag
202             }
203             TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
204                 diag = handler.struct_fatal(fluent::errors_target_inconsistent_architecture);
205                 diag.set_arg("dl", dl);
206                 diag.set_arg("target", target);
207                 diag
208             }
209             TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
210                 diag = handler.struct_fatal(fluent::errors_target_inconsistent_pointer_width);
211                 diag.set_arg("pointer_size", pointer_size);
212                 diag.set_arg("target", target);
213                 diag
214             }
215             TargetDataLayoutErrors::InvalidBitsSize { err } => {
216                 diag = handler.struct_fatal(fluent::errors_target_invalid_bits_size);
217                 diag.set_arg("err", err);
218                 diag
219             }
220         }
221     }
222 }