]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_attr/src/session_diagnostics.rs
Rollup merge of #101046 - notriddle:notriddle/table-css, r=jsha
[rust.git] / compiler / rustc_attr / src / session_diagnostics.rs
1 use std::num::IntErrorKind;
2
3 use rustc_ast as ast;
4 use rustc_errors::{error_code, fluent, Applicability, DiagnosticBuilder, ErrorGuaranteed};
5 use rustc_macros::SessionDiagnostic;
6 use rustc_session::{parse::ParseSess, SessionDiagnostic};
7 use rustc_span::{Span, Symbol};
8
9 use crate::UnsupportedLiteralReason;
10
11 #[derive(SessionDiagnostic)]
12 #[diag(attr::expected_one_cfg_pattern, code = "E0536")]
13 pub(crate) struct ExpectedOneCfgPattern {
14     #[primary_span]
15     pub span: Span,
16 }
17
18 #[derive(SessionDiagnostic)]
19 #[diag(attr::invalid_predicate, code = "E0537")]
20 pub(crate) struct InvalidPredicate {
21     #[primary_span]
22     pub span: Span,
23
24     pub predicate: String,
25 }
26
27 #[derive(SessionDiagnostic)]
28 #[diag(attr::multiple_item, code = "E0538")]
29 pub(crate) struct MultipleItem {
30     #[primary_span]
31     pub span: Span,
32
33     pub item: String,
34 }
35
36 #[derive(SessionDiagnostic)]
37 #[diag(attr::incorrect_meta_item, code = "E0539")]
38 pub(crate) struct IncorrectMetaItem {
39     #[primary_span]
40     pub span: Span,
41 }
42
43 // Error code: E0541
44 pub(crate) struct UnknownMetaItem<'a> {
45     pub span: Span,
46     pub item: String,
47     pub expected: &'a [&'a str],
48 }
49
50 // Manual implementation to be able to format `expected` items correctly.
51 impl<'a> SessionDiagnostic<'a> for UnknownMetaItem<'_> {
52     fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
53         let expected = self.expected.iter().map(|name| format!("`{}`", name)).collect::<Vec<_>>();
54         let mut diag = sess.span_diagnostic.struct_span_err_with_code(
55             self.span,
56             fluent::attr::unknown_meta_item,
57             error_code!(E0541),
58         );
59         diag.set_arg("item", self.item);
60         diag.set_arg("expected", expected.join(", "));
61         diag.span_label(self.span, fluent::attr::label);
62         diag
63     }
64 }
65
66 #[derive(SessionDiagnostic)]
67 #[diag(attr::missing_since, code = "E0542")]
68 pub(crate) struct MissingSince {
69     #[primary_span]
70     pub span: Span,
71 }
72
73 #[derive(SessionDiagnostic)]
74 #[diag(attr::missing_note, code = "E0543")]
75 pub(crate) struct MissingNote {
76     #[primary_span]
77     pub span: Span,
78 }
79
80 #[derive(SessionDiagnostic)]
81 #[diag(attr::multiple_stability_levels, code = "E0544")]
82 pub(crate) struct MultipleStabilityLevels {
83     #[primary_span]
84     pub span: Span,
85 }
86
87 #[derive(SessionDiagnostic)]
88 #[diag(attr::invalid_issue_string, code = "E0545")]
89 pub(crate) struct InvalidIssueString {
90     #[primary_span]
91     pub span: Span,
92
93     #[subdiagnostic]
94     pub cause: Option<InvalidIssueStringCause>,
95 }
96
97 // The error kinds of `IntErrorKind` are duplicated here in order to allow the messages to be
98 // translatable.
99 #[derive(SessionSubdiagnostic)]
100 pub(crate) enum InvalidIssueStringCause {
101     #[label(attr::must_not_be_zero)]
102     MustNotBeZero {
103         #[primary_span]
104         span: Span,
105     },
106
107     #[label(attr::empty)]
108     Empty {
109         #[primary_span]
110         span: Span,
111     },
112
113     #[label(attr::invalid_digit)]
114     InvalidDigit {
115         #[primary_span]
116         span: Span,
117     },
118
119     #[label(attr::pos_overflow)]
120     PosOverflow {
121         #[primary_span]
122         span: Span,
123     },
124
125     #[label(attr::neg_overflow)]
126     NegOverflow {
127         #[primary_span]
128         span: Span,
129     },
130 }
131
132 impl InvalidIssueStringCause {
133     pub fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option<Self> {
134         match kind {
135             IntErrorKind::Empty => Some(Self::Empty { span }),
136             IntErrorKind::InvalidDigit => Some(Self::InvalidDigit { span }),
137             IntErrorKind::PosOverflow => Some(Self::PosOverflow { span }),
138             IntErrorKind::NegOverflow => Some(Self::NegOverflow { span }),
139             IntErrorKind::Zero => Some(Self::MustNotBeZero { span }),
140             _ => None,
141         }
142     }
143 }
144
145 #[derive(SessionDiagnostic)]
146 #[diag(attr::missing_feature, code = "E0546")]
147 pub(crate) struct MissingFeature {
148     #[primary_span]
149     pub span: Span,
150 }
151
152 #[derive(SessionDiagnostic)]
153 #[diag(attr::non_ident_feature, code = "E0546")]
154 pub(crate) struct NonIdentFeature {
155     #[primary_span]
156     pub span: Span,
157 }
158
159 #[derive(SessionDiagnostic)]
160 #[diag(attr::missing_issue, code = "E0547")]
161 pub(crate) struct MissingIssue {
162     #[primary_span]
163     pub span: Span,
164 }
165
166 // FIXME: This diagnostic is identical to `IncorrectMetaItem`, barring the error code. Consider
167 // changing this to `IncorrectMetaItem`. See #51489.
168 #[derive(SessionDiagnostic)]
169 #[diag(attr::incorrect_meta_item, code = "E0551")]
170 pub(crate) struct IncorrectMetaItem2 {
171     #[primary_span]
172     pub span: Span,
173 }
174
175 // FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`?
176 // It is more similar to `IncorrectReprFormatGeneric`.
177 #[derive(SessionDiagnostic)]
178 #[diag(attr::incorrect_repr_format_packed_one_or_zero_arg, code = "E0552")]
179 pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg {
180     #[primary_span]
181     pub span: Span,
182 }
183
184 #[derive(SessionDiagnostic)]
185 #[diag(attr::invalid_repr_hint_no_paren, code = "E0552")]
186 pub(crate) struct InvalidReprHintNoParen {
187     #[primary_span]
188     pub span: Span,
189
190     pub name: String,
191 }
192
193 #[derive(SessionDiagnostic)]
194 #[diag(attr::invalid_repr_hint_no_value, code = "E0552")]
195 pub(crate) struct InvalidReprHintNoValue {
196     #[primary_span]
197     pub span: Span,
198
199     pub name: String,
200 }
201
202 // Error code: E0565
203 pub(crate) struct UnsupportedLiteral {
204     pub span: Span,
205     pub reason: UnsupportedLiteralReason,
206     pub is_bytestr: bool,
207 }
208
209 impl<'a> SessionDiagnostic<'a> for UnsupportedLiteral {
210     fn into_diagnostic(self, sess: &'a ParseSess) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
211         let mut diag = sess.span_diagnostic.struct_span_err_with_code(
212             self.span,
213             match self.reason {
214                 UnsupportedLiteralReason::Generic => fluent::attr::unsupported_literal_generic,
215                 UnsupportedLiteralReason::CfgString => fluent::attr::unsupported_literal_cfg_string,
216                 UnsupportedLiteralReason::DeprecatedString => {
217                     fluent::attr::unsupported_literal_deprecated_string
218                 }
219                 UnsupportedLiteralReason::DeprecatedKvPair => {
220                     fluent::attr::unsupported_literal_deprecated_kv_pair
221                 }
222             },
223             error_code!(E0565),
224         );
225         if self.is_bytestr {
226             if let Ok(lint_str) = sess.source_map().span_to_snippet(self.span) {
227                 diag.span_suggestion(
228                     self.span,
229                     fluent::attr::unsupported_literal_suggestion,
230                     &lint_str[1..],
231                     Applicability::MaybeIncorrect,
232                 );
233             }
234         }
235         diag
236     }
237 }
238
239 #[derive(SessionDiagnostic)]
240 #[diag(attr::invalid_repr_align_need_arg, code = "E0589")]
241 pub(crate) struct InvalidReprAlignNeedArg {
242     #[primary_span]
243     #[suggestion(code = "align(...)", applicability = "has-placeholders")]
244     pub span: Span,
245 }
246
247 #[derive(SessionDiagnostic)]
248 #[diag(attr::invalid_repr_generic, code = "E0589")]
249 pub(crate) struct InvalidReprGeneric<'a> {
250     #[primary_span]
251     pub span: Span,
252
253     pub repr_arg: String,
254     pub error_part: &'a str,
255 }
256
257 #[derive(SessionDiagnostic)]
258 #[diag(attr::incorrect_repr_format_align_one_arg, code = "E0693")]
259 pub(crate) struct IncorrectReprFormatAlignOneArg {
260     #[primary_span]
261     pub span: Span,
262 }
263
264 #[derive(SessionDiagnostic)]
265 #[diag(attr::incorrect_repr_format_generic, code = "E0693")]
266 pub(crate) struct IncorrectReprFormatGeneric<'a> {
267     #[primary_span]
268     pub span: Span,
269
270     pub repr_arg: &'a str,
271
272     #[subdiagnostic]
273     pub cause: Option<IncorrectReprFormatGenericCause<'a>>,
274 }
275
276 #[derive(SessionSubdiagnostic)]
277 pub(crate) enum IncorrectReprFormatGenericCause<'a> {
278     #[suggestion(attr::suggestion, code = "{name}({int})", applicability = "machine-applicable")]
279     Int {
280         #[primary_span]
281         span: Span,
282
283         #[skip_arg]
284         name: &'a str,
285
286         #[skip_arg]
287         int: u128,
288     },
289
290     #[suggestion(
291         attr::suggestion,
292         code = "{name}({symbol})",
293         applicability = "machine-applicable"
294     )]
295     Symbol {
296         #[primary_span]
297         span: Span,
298
299         #[skip_arg]
300         name: &'a str,
301
302         #[skip_arg]
303         symbol: Symbol,
304     },
305 }
306
307 impl<'a> IncorrectReprFormatGenericCause<'a> {
308     pub fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
309         match kind {
310             ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
311                 Some(Self::Int { span, name, int: *int })
312             }
313             ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }),
314             _ => None,
315         }
316     }
317 }
318
319 #[derive(SessionDiagnostic)]
320 #[diag(attr::rustc_promotable_pairing, code = "E0717")]
321 pub(crate) struct RustcPromotablePairing {
322     #[primary_span]
323     pub span: Span,
324 }
325
326 #[derive(SessionDiagnostic)]
327 #[diag(attr::rustc_allowed_unstable_pairing, code = "E0789")]
328 pub(crate) struct RustcAllowedUnstablePairing {
329     #[primary_span]
330     pub span: Span,
331 }
332
333 #[derive(SessionDiagnostic)]
334 #[diag(attr::cfg_predicate_identifier)]
335 pub(crate) struct CfgPredicateIdentifier {
336     #[primary_span]
337     pub span: Span,
338 }
339
340 #[derive(SessionDiagnostic)]
341 #[diag(attr::deprecated_item_suggestion)]
342 pub(crate) struct DeprecatedItemSuggestion {
343     #[primary_span]
344     pub span: Span,
345
346     #[help]
347     pub is_nightly: Option<()>,
348
349     #[note]
350     pub details: (),
351 }
352
353 #[derive(SessionDiagnostic)]
354 #[diag(attr::expected_single_version_literal)]
355 pub(crate) struct ExpectedSingleVersionLiteral {
356     #[primary_span]
357     pub span: Span,
358 }
359
360 #[derive(SessionDiagnostic)]
361 #[diag(attr::expected_version_literal)]
362 pub(crate) struct ExpectedVersionLiteral {
363     #[primary_span]
364     pub span: Span,
365 }
366
367 #[derive(SessionDiagnostic)]
368 #[diag(attr::expects_feature_list)]
369 pub(crate) struct ExpectsFeatureList {
370     #[primary_span]
371     pub span: Span,
372
373     pub name: String,
374 }
375
376 #[derive(SessionDiagnostic)]
377 #[diag(attr::expects_features)]
378 pub(crate) struct ExpectsFeatures {
379     #[primary_span]
380     pub span: Span,
381
382     pub name: String,
383 }
384
385 #[derive(SessionDiagnostic)]
386 #[diag(attr::soft_no_args)]
387 pub(crate) struct SoftNoArgs {
388     #[primary_span]
389     pub span: Span,
390 }
391
392 #[derive(SessionDiagnostic)]
393 #[diag(attr::unknown_version_literal)]
394 pub(crate) struct UnknownVersionLiteral {
395     #[primary_span]
396     pub span: Span,
397 }