1use std::num::IntErrorKind;
2
3use rustc_ast as ast;
4use rustc_errors::codes::*;
5use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level};
6use rustc_macros::{Diagnostic, Subdiagnostic};
7use rustc_span::{Span, Symbol};
8
9use crate::fluent_generated as fluent;
10
11pub(crate) enum UnsupportedLiteralReason {
12 Generic,
13 CfgString,
14 CfgBoolean,
15 DeprecatedString,
16 DeprecatedKvPair,
17}
18
19#[derive(Diagnostic)]
20#[diag(attr_parsing_expected_one_cfg_pattern, code = E0536)]
21pub(crate) struct ExpectedOneCfgPattern {
22 #[primary_span]
23 pub span: Span,
24}
25
26#[derive(Diagnostic)]
27#[diag(attr_parsing_invalid_predicate, code = E0537)]
28pub(crate) struct InvalidPredicate {
29 #[primary_span]
30 pub span: Span,
31
32 pub predicate: String,
33}
34
35#[derive(Diagnostic)]
36#[diag(attr_parsing_multiple_item, code = E0538)]
37pub(crate) struct MultipleItem {
38 #[primary_span]
39 pub span: Span,
40
41 pub item: String,
42}
43
44#[derive(Diagnostic)]
45#[diag(attr_parsing_incorrect_meta_item, code = E0539)]
46pub(crate) struct IncorrectMetaItem {
47 #[primary_span]
48 pub span: Span,
49
50 #[subdiagnostic]
51 pub suggestion: Option<IncorrectMetaItemSuggestion>,
52}
53
54#[derive(Subdiagnostic)]
55#[multipart_suggestion(
56 attr_parsing_incorrect_meta_item_suggestion,
57 applicability = "maybe-incorrect"
58)]
59pub(crate) struct IncorrectMetaItemSuggestion {
60 #[suggestion_part(code = "\"")]
61 pub lo: Span,
62 #[suggestion_part(code = "\"")]
63 pub hi: Span,
64}
65
66pub(crate) struct UnknownMetaItem<'a> {
68 pub span: Span,
69 pub item: String,
70 pub expected: &'a [&'a str],
71}
72
73impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnknownMetaItem<'_> {
75 fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
76 let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::<Vec<_>>();
77 Diag::new(dcx, level, fluent::attr_parsing_unknown_meta_item)
78 .with_span(self.span)
79 .with_code(E0541)
80 .with_arg("item", self.item)
81 .with_arg("expected", expected.join(", "))
82 .with_span_label(self.span, fluent::attr_parsing_label)
83 }
84}
85
86#[derive(Diagnostic)]
87#[diag(attr_parsing_missing_since, code = E0542)]
88pub(crate) struct MissingSince {
89 #[primary_span]
90 pub span: Span,
91}
92
93#[derive(Diagnostic)]
94#[diag(attr_parsing_missing_note, code = E0543)]
95pub(crate) struct MissingNote {
96 #[primary_span]
97 pub span: Span,
98}
99
100#[derive(Diagnostic)]
101#[diag(attr_parsing_multiple_stability_levels, code = E0544)]
102pub(crate) struct MultipleStabilityLevels {
103 #[primary_span]
104 pub span: Span,
105}
106
107#[derive(Diagnostic)]
108#[diag(attr_parsing_invalid_issue_string, code = E0545)]
109pub(crate) struct InvalidIssueString {
110 #[primary_span]
111 pub span: Span,
112
113 #[subdiagnostic]
114 pub cause: Option<InvalidIssueStringCause>,
115}
116
117#[derive(Subdiagnostic)]
120pub(crate) enum InvalidIssueStringCause {
121 #[label(attr_parsing_must_not_be_zero)]
122 MustNotBeZero {
123 #[primary_span]
124 span: Span,
125 },
126
127 #[label(attr_parsing_empty)]
128 Empty {
129 #[primary_span]
130 span: Span,
131 },
132
133 #[label(attr_parsing_invalid_digit)]
134 InvalidDigit {
135 #[primary_span]
136 span: Span,
137 },
138
139 #[label(attr_parsing_pos_overflow)]
140 PosOverflow {
141 #[primary_span]
142 span: Span,
143 },
144
145 #[label(attr_parsing_neg_overflow)]
146 NegOverflow {
147 #[primary_span]
148 span: Span,
149 },
150}
151
152impl InvalidIssueStringCause {
153 pub(crate) fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option<Self> {
154 match kind {
155 IntErrorKind::Empty => Some(Self::Empty { span }),
156 IntErrorKind::InvalidDigit => Some(Self::InvalidDigit { span }),
157 IntErrorKind::PosOverflow => Some(Self::PosOverflow { span }),
158 IntErrorKind::NegOverflow => Some(Self::NegOverflow { span }),
159 IntErrorKind::Zero => Some(Self::MustNotBeZero { span }),
160 _ => None,
161 }
162 }
163}
164
165#[derive(Diagnostic)]
166#[diag(attr_parsing_missing_feature, code = E0546)]
167pub(crate) struct MissingFeature {
168 #[primary_span]
169 pub span: Span,
170}
171
172#[derive(Diagnostic)]
173#[diag(attr_parsing_non_ident_feature, code = E0546)]
174pub(crate) struct NonIdentFeature {
175 #[primary_span]
176 pub span: Span,
177}
178
179#[derive(Diagnostic)]
180#[diag(attr_parsing_missing_issue, code = E0547)]
181pub(crate) struct MissingIssue {
182 #[primary_span]
183 pub span: Span,
184}
185
186#[derive(Diagnostic)]
189#[diag(attr_parsing_incorrect_repr_format_packed_one_or_zero_arg, code = E0552)]
190pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg {
191 #[primary_span]
192 pub span: Span,
193}
194#[derive(Diagnostic)]
195#[diag(attr_parsing_incorrect_repr_format_packed_expect_integer, code = E0552)]
196pub(crate) struct IncorrectReprFormatPackedExpectInteger {
197 #[primary_span]
198 pub span: Span,
199}
200
201#[derive(Diagnostic)]
202#[diag(attr_parsing_invalid_repr_hint_no_paren, code = E0552)]
203pub(crate) struct InvalidReprHintNoParen {
204 #[primary_span]
205 pub span: Span,
206
207 pub name: String,
208}
209
210#[derive(Diagnostic)]
211#[diag(attr_parsing_invalid_repr_hint_no_value, code = E0552)]
212pub(crate) struct InvalidReprHintNoValue {
213 #[primary_span]
214 pub span: Span,
215
216 pub name: String,
217}
218
219pub(crate) struct UnsupportedLiteral {
221 pub span: Span,
222 pub reason: UnsupportedLiteralReason,
223 pub is_bytestr: bool,
224 pub start_point_span: Span,
225}
226
227impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnsupportedLiteral {
228 fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
229 let mut diag = Diag::new(
230 dcx,
231 level,
232 match self.reason {
233 UnsupportedLiteralReason::Generic => {
234 fluent::attr_parsing_unsupported_literal_generic
235 }
236 UnsupportedLiteralReason::CfgString => {
237 fluent::attr_parsing_unsupported_literal_cfg_string
238 }
239 UnsupportedLiteralReason::CfgBoolean => {
240 fluent::attr_parsing_unsupported_literal_cfg_boolean
241 }
242 UnsupportedLiteralReason::DeprecatedString => {
243 fluent::attr_parsing_unsupported_literal_deprecated_string
244 }
245 UnsupportedLiteralReason::DeprecatedKvPair => {
246 fluent::attr_parsing_unsupported_literal_deprecated_kv_pair
247 }
248 },
249 );
250 diag.span(self.span);
251 diag.code(E0565);
252 if self.is_bytestr {
253 diag.span_suggestion(
254 self.start_point_span,
255 fluent::attr_parsing_unsupported_literal_suggestion,
256 "",
257 Applicability::MaybeIncorrect,
258 );
259 }
260 diag
261 }
262}
263
264#[derive(Diagnostic)]
265#[diag(attr_parsing_invalid_repr_align_need_arg, code = E0589)]
266pub(crate) struct InvalidReprAlignNeedArg {
267 #[primary_span]
268 #[suggestion(code = "align(...)", applicability = "has-placeholders")]
269 pub span: Span,
270}
271
272#[derive(Diagnostic)]
273#[diag(attr_parsing_invalid_repr_generic, code = E0589)]
274pub(crate) struct InvalidReprGeneric<'a> {
275 #[primary_span]
276 pub span: Span,
277
278 pub repr_arg: String,
279 pub error_part: &'a str,
280}
281
282#[derive(Diagnostic)]
283#[diag(attr_parsing_incorrect_repr_format_align_one_arg, code = E0693)]
284pub(crate) struct IncorrectReprFormatAlignOneArg {
285 #[primary_span]
286 pub span: Span,
287}
288
289#[derive(Diagnostic)]
290#[diag(attr_parsing_incorrect_repr_format_expect_literal_integer, code = E0693)]
291pub(crate) struct IncorrectReprFormatExpectInteger {
292 #[primary_span]
293 pub span: Span,
294}
295
296#[derive(Diagnostic)]
297#[diag(attr_parsing_incorrect_repr_format_generic, code = E0693)]
298pub(crate) struct IncorrectReprFormatGeneric<'a> {
299 #[primary_span]
300 pub span: Span,
301
302 pub repr_arg: &'a str,
303
304 #[subdiagnostic]
305 pub cause: Option<IncorrectReprFormatGenericCause<'a>>,
306}
307
308#[derive(Subdiagnostic)]
309pub(crate) enum IncorrectReprFormatGenericCause<'a> {
310 #[suggestion(
311 attr_parsing_suggestion,
312 code = "{name}({int})",
313 applicability = "machine-applicable"
314 )]
315 Int {
316 #[primary_span]
317 span: Span,
318
319 #[skip_arg]
320 name: &'a str,
321
322 #[skip_arg]
323 int: u128,
324 },
325
326 #[suggestion(
327 attr_parsing_suggestion,
328 code = "{name}({symbol})",
329 applicability = "machine-applicable"
330 )]
331 Symbol {
332 #[primary_span]
333 span: Span,
334
335 #[skip_arg]
336 name: &'a str,
337
338 #[skip_arg]
339 symbol: Symbol,
340 },
341}
342
343impl<'a> IncorrectReprFormatGenericCause<'a> {
344 pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
345 match kind {
346 ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
347 Some(Self::Int { span, name, int: int.get() })
348 }
349 ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }),
350 _ => None,
351 }
352 }
353}
354
355#[derive(Diagnostic)]
356#[diag(attr_parsing_rustc_promotable_pairing, code = E0717)]
357pub(crate) struct RustcPromotablePairing {
358 #[primary_span]
359 pub span: Span,
360}
361
362#[derive(Diagnostic)]
363#[diag(attr_parsing_rustc_allowed_unstable_pairing, code = E0789)]
364pub(crate) struct RustcAllowedUnstablePairing {
365 #[primary_span]
366 pub span: Span,
367}
368
369#[derive(Diagnostic)]
370#[diag(attr_parsing_cfg_predicate_identifier)]
371pub(crate) struct CfgPredicateIdentifier {
372 #[primary_span]
373 pub span: Span,
374}
375
376#[derive(Diagnostic)]
377#[diag(attr_parsing_deprecated_item_suggestion)]
378pub(crate) struct DeprecatedItemSuggestion {
379 #[primary_span]
380 pub span: Span,
381
382 #[help]
383 pub is_nightly: bool,
384
385 #[note]
386 pub details: (),
387}
388
389#[derive(Diagnostic)]
390#[diag(attr_parsing_expected_single_version_literal)]
391pub(crate) struct ExpectedSingleVersionLiteral {
392 #[primary_span]
393 pub span: Span,
394}
395
396#[derive(Diagnostic)]
397#[diag(attr_parsing_expected_version_literal)]
398pub(crate) struct ExpectedVersionLiteral {
399 #[primary_span]
400 pub span: Span,
401}
402
403#[derive(Diagnostic)]
404#[diag(attr_parsing_expects_feature_list)]
405pub(crate) struct ExpectsFeatureList {
406 #[primary_span]
407 pub span: Span,
408
409 pub name: String,
410}
411
412#[derive(Diagnostic)]
413#[diag(attr_parsing_expects_features)]
414pub(crate) struct ExpectsFeatures {
415 #[primary_span]
416 pub span: Span,
417
418 pub name: String,
419}
420
421#[derive(Diagnostic)]
422#[diag(attr_parsing_invalid_since)]
423pub(crate) struct InvalidSince {
424 #[primary_span]
425 pub span: Span,
426}
427
428#[derive(Diagnostic)]
429#[diag(attr_parsing_soft_no_args)]
430pub(crate) struct SoftNoArgs {
431 #[primary_span]
432 pub span: Span,
433}
434
435#[derive(Diagnostic)]
436#[diag(attr_parsing_unknown_version_literal)]
437pub(crate) struct UnknownVersionLiteral {
438 #[primary_span]
439 pub span: Span,
440}
441
442#[derive(Diagnostic)]
444#[diag(attr_parsing_unused_multiple)]
445pub(crate) struct UnusedMultiple {
446 #[primary_span]
447 #[suggestion(code = "", applicability = "machine-applicable")]
448 pub this: Span,
449 #[note]
450 pub other: Span,
451 pub name: Symbol,
452}
453
454#[derive(Diagnostic)]
455#[diag(attr_parsing_stability_outside_std, code = E0734)]
456pub(crate) struct StabilityOutsideStd {
457 #[primary_span]
458 pub span: Span,
459}
460
461#[derive(Diagnostic)]
462#[diag(attr_parsing_empty_confusables)]
463pub(crate) struct EmptyConfusables {
464 #[primary_span]
465 pub span: Span,
466}
467
468#[derive(Diagnostic)]
469#[diag(attr_parsing_repr_ident, code = E0565)]
470pub(crate) struct ReprIdent {
471 #[primary_span]
472 pub span: Span,
473}
474
475#[derive(Diagnostic)]
476#[diag(attr_parsing_unrecognized_repr_hint, code = E0552)]
477#[help]
478pub(crate) struct UnrecognizedReprHint {
479 #[primary_span]
480 pub span: Span,
481}