rustc_attr_parsing/
session_diagnostics.rs

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
44/// Error code: E0541
45pub(crate) struct UnknownMetaItem<'a> {
46    pub span: Span,
47    pub item: String,
48    pub expected: &'a [&'a str],
49}
50
51// Manual implementation to be able to format `expected` items correctly.
52impl<'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// The error kinds of `IntErrorKind` are duplicated here in order to allow the messages to be
96// translatable.
97#[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// FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`?
165// It is more similar to `IncorrectReprFormatGeneric`.
166#[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
197/// Error code: E0565
198pub(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}