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