1 use std::num::IntErrorKind;
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};
9 use crate::UnsupportedLiteralReason;
11 #[derive(SessionDiagnostic)]
12 #[diag(attr::expected_one_cfg_pattern, code = "E0536")]
13 pub(crate) struct ExpectedOneCfgPattern {
18 #[derive(SessionDiagnostic)]
19 #[diag(attr::invalid_predicate, code = "E0537")]
20 pub(crate) struct InvalidPredicate {
24 pub predicate: String,
27 #[derive(SessionDiagnostic)]
28 #[diag(attr::multiple_item, code = "E0538")]
29 pub(crate) struct MultipleItem {
36 #[derive(SessionDiagnostic)]
37 #[diag(attr::incorrect_meta_item, code = "E0539")]
38 pub(crate) struct IncorrectMetaItem {
44 pub(crate) struct UnknownMetaItem<'a> {
47 pub expected: &'a [&'a str],
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(
56 fluent::attr::unknown_meta_item,
59 diag.set_arg("item", self.item);
60 diag.set_arg("expected", expected.join(", "));
61 diag.span_label(self.span, fluent::attr::label);
66 #[derive(SessionDiagnostic)]
67 #[diag(attr::missing_since, code = "E0542")]
68 pub(crate) struct MissingSince {
73 #[derive(SessionDiagnostic)]
74 #[diag(attr::missing_note, code = "E0543")]
75 pub(crate) struct MissingNote {
80 #[derive(SessionDiagnostic)]
81 #[diag(attr::multiple_stability_levels, code = "E0544")]
82 pub(crate) struct MultipleStabilityLevels {
87 #[derive(SessionDiagnostic)]
88 #[diag(attr::invalid_issue_string, code = "E0545")]
89 pub(crate) struct InvalidIssueString {
94 pub cause: Option<InvalidIssueStringCause>,
97 // The error kinds of `IntErrorKind` are duplicated here in order to allow the messages to be
99 #[derive(SessionSubdiagnostic)]
100 pub(crate) enum InvalidIssueStringCause {
101 #[label(attr::must_not_be_zero)]
107 #[label(attr::empty)]
113 #[label(attr::invalid_digit)]
119 #[label(attr::pos_overflow)]
125 #[label(attr::neg_overflow)]
132 impl InvalidIssueStringCause {
133 pub fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option<Self> {
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 }),
145 #[derive(SessionDiagnostic)]
146 #[diag(attr::missing_feature, code = "E0546")]
147 pub(crate) struct MissingFeature {
152 #[derive(SessionDiagnostic)]
153 #[diag(attr::non_ident_feature, code = "E0546")]
154 pub(crate) struct NonIdentFeature {
159 #[derive(SessionDiagnostic)]
160 #[diag(attr::missing_issue, code = "E0547")]
161 pub(crate) struct MissingIssue {
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 {
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 {
184 #[derive(SessionDiagnostic)]
185 #[diag(attr::invalid_repr_hint_no_paren, code = "E0552")]
186 pub(crate) struct InvalidReprHintNoParen {
193 #[derive(SessionDiagnostic)]
194 #[diag(attr::invalid_repr_hint_no_value, code = "E0552")]
195 pub(crate) struct InvalidReprHintNoValue {
203 pub(crate) struct UnsupportedLiteral {
205 pub reason: UnsupportedLiteralReason,
206 pub is_bytestr: bool,
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(
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
219 UnsupportedLiteralReason::DeprecatedKvPair => {
220 fluent::attr::unsupported_literal_deprecated_kv_pair
226 if let Ok(lint_str) = sess.source_map().span_to_snippet(self.span) {
227 diag.span_suggestion(
229 fluent::attr::unsupported_literal_suggestion,
231 Applicability::MaybeIncorrect,
239 #[derive(SessionDiagnostic)]
240 #[diag(attr::invalid_repr_align_need_arg, code = "E0589")]
241 pub(crate) struct InvalidReprAlignNeedArg {
243 #[suggestion(code = "align(...)", applicability = "has-placeholders")]
247 #[derive(SessionDiagnostic)]
248 #[diag(attr::invalid_repr_generic, code = "E0589")]
249 pub(crate) struct InvalidReprGeneric<'a> {
253 pub repr_arg: String,
254 pub error_part: &'a str,
257 #[derive(SessionDiagnostic)]
258 #[diag(attr::incorrect_repr_format_align_one_arg, code = "E0693")]
259 pub(crate) struct IncorrectReprFormatAlignOneArg {
264 #[derive(SessionDiagnostic)]
265 #[diag(attr::incorrect_repr_format_generic, code = "E0693")]
266 pub(crate) struct IncorrectReprFormatGeneric<'a> {
270 pub repr_arg: &'a str,
273 pub cause: Option<IncorrectReprFormatGenericCause<'a>>,
276 #[derive(SessionSubdiagnostic)]
277 pub(crate) enum IncorrectReprFormatGenericCause<'a> {
278 #[suggestion(attr::suggestion, code = "{name}({int})", applicability = "machine-applicable")]
292 code = "{name}({symbol})",
293 applicability = "machine-applicable"
307 impl<'a> IncorrectReprFormatGenericCause<'a> {
308 pub fn from_lit_kind(span: Span, kind: &ast::LitKind, name: &'a str) -> Option<Self> {
310 ast::LitKind::Int(int, ast::LitIntType::Unsuffixed) => {
311 Some(Self::Int { span, name, int: *int })
313 ast::LitKind::Str(symbol, _) => Some(Self::Symbol { span, name, symbol: *symbol }),
319 #[derive(SessionDiagnostic)]
320 #[diag(attr::rustc_promotable_pairing, code = "E0717")]
321 pub(crate) struct RustcPromotablePairing {
326 #[derive(SessionDiagnostic)]
327 #[diag(attr::rustc_allowed_unstable_pairing, code = "E0789")]
328 pub(crate) struct RustcAllowedUnstablePairing {
333 #[derive(SessionDiagnostic)]
334 #[diag(attr::cfg_predicate_identifier)]
335 pub(crate) struct CfgPredicateIdentifier {
340 #[derive(SessionDiagnostic)]
341 #[diag(attr::deprecated_item_suggestion)]
342 pub(crate) struct DeprecatedItemSuggestion {
347 pub is_nightly: Option<()>,
353 #[derive(SessionDiagnostic)]
354 #[diag(attr::expected_single_version_literal)]
355 pub(crate) struct ExpectedSingleVersionLiteral {
360 #[derive(SessionDiagnostic)]
361 #[diag(attr::expected_version_literal)]
362 pub(crate) struct ExpectedVersionLiteral {
367 #[derive(SessionDiagnostic)]
368 #[diag(attr::expects_feature_list)]
369 pub(crate) struct ExpectsFeatureList {
376 #[derive(SessionDiagnostic)]
377 #[diag(attr::expects_features)]
378 pub(crate) struct ExpectsFeatures {
385 #[derive(SessionDiagnostic)]
386 #[diag(attr::soft_no_args)]
387 pub(crate) struct SoftNoArgs {
392 #[derive(SessionDiagnostic)]
393 #[diag(attr::unknown_version_literal)]
394 pub(crate) struct UnknownVersionLiteral {