rustc_attr_parsing/
session_diagnostics.rs

1use std::num::IntErrorKind;
2
3use rustc_ast::{self as ast};
4use rustc_errors::codes::*;
5use rustc_errors::{
6    Applicability, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level,
7};
8use rustc_feature::AttributeTemplate;
9use rustc_hir::AttrPath;
10use rustc_macros::{Diagnostic, Subdiagnostic};
11use rustc_span::{Span, Symbol};
12use rustc_target::spec::TargetTuple;
13
14use crate::fluent_generated as fluent;
15
16#[derive(Diagnostic)]
17#[diag(attr_parsing_invalid_predicate, code = E0537)]
18pub(crate) struct InvalidPredicate {
19    #[primary_span]
20    pub span: Span,
21
22    pub predicate: String,
23}
24
25#[derive(Diagnostic)]
26#[diag(attr_parsing_doc_alias_empty)]
27pub(crate) struct DocAliasEmpty<'a> {
28    #[primary_span]
29    pub span: Span,
30    pub attr_str: &'a str,
31}
32
33#[derive(Diagnostic)]
34#[diag(attr_parsing_doc_alias_bad_char)]
35pub(crate) struct DocAliasBadChar<'a> {
36    #[primary_span]
37    pub span: Span,
38    pub attr_str: &'a str,
39    pub char_: char,
40}
41
42#[derive(Diagnostic)]
43#[diag(attr_parsing_doc_alias_start_end)]
44pub(crate) struct DocAliasStartEnd<'a> {
45    #[primary_span]
46    pub span: Span,
47    pub attr_str: &'a str,
48}
49
50#[derive(Diagnostic)]
51#[diag(attr_parsing_doc_keyword_not_keyword)]
52#[help]
53pub(crate) struct DocKeywordNotKeyword {
54    #[primary_span]
55    pub span: Span,
56    pub keyword: Symbol,
57}
58
59#[derive(Diagnostic)]
60#[diag(attr_parsing_doc_attribute_not_attribute)]
61#[help]
62pub(crate) struct DocAttributeNotAttribute {
63    #[primary_span]
64    pub span: Span,
65    pub attribute: Symbol,
66}
67
68#[derive(Diagnostic)]
69#[diag(attr_parsing_missing_since, code = E0542)]
70pub(crate) struct MissingSince {
71    #[primary_span]
72    pub span: Span,
73}
74
75#[derive(Diagnostic)]
76#[diag(attr_parsing_missing_note, code = E0543)]
77pub(crate) struct MissingNote {
78    #[primary_span]
79    pub span: Span,
80}
81
82#[derive(Diagnostic)]
83#[diag(attr_parsing_multiple_stability_levels, code = E0544)]
84pub(crate) struct MultipleStabilityLevels {
85    #[primary_span]
86    pub span: Span,
87}
88
89#[derive(Diagnostic)]
90#[diag(attr_parsing_invalid_issue_string, code = E0545)]
91pub(crate) struct InvalidIssueString {
92    #[primary_span]
93    pub span: Span,
94
95    #[subdiagnostic]
96    pub cause: Option<InvalidIssueStringCause>,
97}
98
99// The error kinds of `IntErrorKind` are duplicated here in order to allow the messages to be
100// translatable.
101#[derive(Subdiagnostic)]
102pub(crate) enum InvalidIssueStringCause {
103    #[label(attr_parsing_must_not_be_zero)]
104    MustNotBeZero {
105        #[primary_span]
106        span: Span,
107    },
108
109    #[label(attr_parsing_empty)]
110    Empty {
111        #[primary_span]
112        span: Span,
113    },
114
115    #[label(attr_parsing_invalid_digit)]
116    InvalidDigit {
117        #[primary_span]
118        span: Span,
119    },
120
121    #[label(attr_parsing_pos_overflow)]
122    PosOverflow {
123        #[primary_span]
124        span: Span,
125    },
126
127    #[label(attr_parsing_neg_overflow)]
128    NegOverflow {
129        #[primary_span]
130        span: Span,
131    },
132}
133
134impl InvalidIssueStringCause {
135    pub(crate) fn from_int_error_kind(span: Span, kind: &IntErrorKind) -> Option<Self> {
136        match kind {
137            IntErrorKind::Empty => Some(Self::Empty { span }),
138            IntErrorKind::InvalidDigit => Some(Self::InvalidDigit { span }),
139            IntErrorKind::PosOverflow => Some(Self::PosOverflow { span }),
140            IntErrorKind::NegOverflow => Some(Self::NegOverflow { span }),
141            IntErrorKind::Zero => Some(Self::MustNotBeZero { span }),
142            _ => None,
143        }
144    }
145}
146
147#[derive(Diagnostic)]
148#[diag(attr_parsing_missing_feature, code = E0546)]
149pub(crate) struct MissingFeature {
150    #[primary_span]
151    pub span: Span,
152}
153
154#[derive(Diagnostic)]
155#[diag(attr_parsing_non_ident_feature, code = E0546)]
156pub(crate) struct NonIdentFeature {
157    #[primary_span]
158    pub span: Span,
159}
160
161#[derive(Diagnostic)]
162#[diag(attr_parsing_missing_issue, code = E0547)]
163pub(crate) struct MissingIssue {
164    #[primary_span]
165    pub span: Span,
166}
167
168// FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`?
169// It is more similar to `IncorrectReprFormatGeneric`.
170#[derive(Diagnostic)]
171#[diag(attr_parsing_incorrect_repr_format_packed_one_or_zero_arg, code = E0552)]
172pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg {
173    #[primary_span]
174    pub span: Span,
175}
176#[derive(Diagnostic)]
177#[diag(attr_parsing_incorrect_repr_format_packed_expect_integer, code = E0552)]
178pub(crate) struct IncorrectReprFormatPackedExpectInteger {
179    #[primary_span]
180    pub span: Span,
181}
182
183#[derive(Diagnostic)]
184#[diag(attr_parsing_invalid_repr_hint_no_paren, code = E0552)]
185pub(crate) struct InvalidReprHintNoParen {
186    #[primary_span]
187    pub span: Span,
188
189    pub name: Symbol,
190}
191
192#[derive(Diagnostic)]
193#[diag(attr_parsing_invalid_repr_hint_no_value, code = E0552)]
194pub(crate) struct InvalidReprHintNoValue {
195    #[primary_span]
196    pub span: Span,
197
198    pub name: Symbol,
199}
200
201#[derive(Diagnostic)]
202#[diag(attr_parsing_invalid_repr_align_need_arg, code = E0589)]
203pub(crate) struct InvalidReprAlignNeedArg {
204    #[primary_span]
205    #[suggestion(code = "align(...)", applicability = "has-placeholders")]
206    pub span: Span,
207}
208
209#[derive(Diagnostic)]
210#[diag(attr_parsing_invalid_repr_generic, code = E0589)]
211pub(crate) struct InvalidReprGeneric<'a> {
212    #[primary_span]
213    pub span: Span,
214
215    pub repr_arg: String,
216    pub error_part: &'a str,
217}
218
219#[derive(Diagnostic)]
220#[diag(attr_parsing_incorrect_repr_format_align_one_arg, code = E0693)]
221pub(crate) struct IncorrectReprFormatAlignOneArg {
222    #[primary_span]
223    pub span: Span,
224}
225
226#[derive(Diagnostic)]
227#[diag(attr_parsing_incorrect_repr_format_expect_literal_integer, code = E0693)]
228pub(crate) struct IncorrectReprFormatExpectInteger {
229    #[primary_span]
230    pub span: Span,
231}
232
233#[derive(Diagnostic)]
234#[diag(attr_parsing_incorrect_repr_format_generic, code = E0693)]
235pub(crate) struct IncorrectReprFormatGeneric {
236    #[primary_span]
237    pub span: Span,
238
239    pub repr_arg: Symbol,
240
241    #[subdiagnostic]
242    pub cause: Option<IncorrectReprFormatGenericCause>,
243}
244
245#[derive(Subdiagnostic)]
246pub(crate) enum IncorrectReprFormatGenericCause {
247    #[suggestion(
248        attr_parsing_suggestion,
249        code = "{name}({value})",
250        applicability = "machine-applicable"
251    )]
252    Int {
253        #[primary_span]
254        span: Span,
255
256        #[skip_arg]
257        name: Symbol,
258
259        #[skip_arg]
260        value: u128,
261    },
262
263    #[suggestion(
264        attr_parsing_suggestion,
265        code = "{name}({value})",
266        applicability = "machine-applicable"
267    )]
268    Symbol {
269        #[primary_span]
270        span: Span,
271
272        #[skip_arg]
273        name: Symbol,
274
275        #[skip_arg]
276        value: Symbol,
277    },
278}
279
280impl IncorrectReprFormatGenericCause {
281    pub(crate) fn from_lit_kind(span: Span, kind: &ast::LitKind, name: Symbol) -> Option<Self> {
282        match *kind {
283            ast::LitKind::Int(value, ast::LitIntType::Unsuffixed) => {
284                Some(Self::Int { span, name, value: value.get() })
285            }
286            ast::LitKind::Str(value, _) => Some(Self::Symbol { span, name, value }),
287            _ => None,
288        }
289    }
290}
291
292#[derive(Diagnostic)]
293#[diag(attr_parsing_rustc_promotable_pairing, code = E0717)]
294pub(crate) struct RustcPromotablePairing {
295    #[primary_span]
296    pub span: Span,
297}
298
299#[derive(Diagnostic)]
300#[diag(attr_parsing_rustc_allowed_unstable_pairing, code = E0789)]
301pub(crate) struct RustcAllowedUnstablePairing {
302    #[primary_span]
303    pub span: Span,
304}
305
306#[derive(Diagnostic)]
307#[diag(attr_parsing_deprecated_item_suggestion)]
308pub(crate) struct DeprecatedItemSuggestion {
309    #[primary_span]
310    pub span: Span,
311
312    #[help]
313    pub is_nightly: bool,
314
315    #[note]
316    pub details: (),
317}
318
319#[derive(Diagnostic)]
320#[diag(attr_parsing_expected_single_version_literal)]
321pub(crate) struct ExpectedSingleVersionLiteral {
322    #[primary_span]
323    pub span: Span,
324}
325
326#[derive(Diagnostic)]
327#[diag(attr_parsing_expected_version_literal)]
328pub(crate) struct ExpectedVersionLiteral {
329    #[primary_span]
330    pub span: Span,
331}
332
333#[derive(Diagnostic)]
334#[diag(attr_parsing_expects_feature_list)]
335pub(crate) struct ExpectsFeatureList {
336    #[primary_span]
337    pub span: Span,
338
339    pub name: String,
340}
341
342#[derive(Diagnostic)]
343#[diag(attr_parsing_expects_features)]
344pub(crate) struct ExpectsFeatures {
345    #[primary_span]
346    pub span: Span,
347
348    pub name: String,
349}
350
351#[derive(Diagnostic)]
352#[diag(attr_parsing_invalid_since)]
353pub(crate) struct InvalidSince {
354    #[primary_span]
355    pub span: Span,
356}
357
358#[derive(Diagnostic)]
359#[diag(attr_parsing_soft_no_args)]
360pub(crate) struct SoftNoArgs {
361    #[primary_span]
362    pub span: Span,
363}
364
365#[derive(Diagnostic)]
366#[diag(attr_parsing_unknown_version_literal)]
367pub(crate) struct UnknownVersionLiteral {
368    #[primary_span]
369    pub span: Span,
370}
371
372// FIXME(jdonszelmann) duplicated from `rustc_passes`, remove once `check_attr` is integrated.
373#[derive(Diagnostic)]
374#[diag(attr_parsing_unused_multiple)]
375pub(crate) struct UnusedMultiple {
376    #[primary_span]
377    #[suggestion(code = "", applicability = "machine-applicable")]
378    pub this: Span,
379    #[note]
380    pub other: Span,
381    pub name: Symbol,
382}
383
384#[derive(Diagnostic)]
385#[diag(attr_parsing_null_on_export, code = E0648)]
386pub(crate) struct NullOnExport {
387    #[primary_span]
388    pub span: Span,
389}
390
391#[derive(Diagnostic)]
392#[diag(attr_parsing_null_on_link_section, code = E0648)]
393pub(crate) struct NullOnLinkSection {
394    #[primary_span]
395    pub span: Span,
396}
397
398#[derive(Diagnostic)]
399#[diag(attr_parsing_null_on_objc_class)]
400pub(crate) struct NullOnObjcClass {
401    #[primary_span]
402    pub span: Span,
403}
404
405#[derive(Diagnostic)]
406#[diag(attr_parsing_null_on_objc_selector)]
407pub(crate) struct NullOnObjcSelector {
408    #[primary_span]
409    pub span: Span,
410}
411
412#[derive(Diagnostic)]
413#[diag(attr_parsing_objc_class_expected_string_literal)]
414pub(crate) struct ObjcClassExpectedStringLiteral {
415    #[primary_span]
416    pub span: Span,
417}
418
419#[derive(Diagnostic)]
420#[diag(attr_parsing_objc_selector_expected_string_literal)]
421pub(crate) struct ObjcSelectorExpectedStringLiteral {
422    #[primary_span]
423    pub span: Span,
424}
425
426#[derive(Diagnostic)]
427#[diag(attr_parsing_stability_outside_std, code = E0734)]
428pub(crate) struct StabilityOutsideStd {
429    #[primary_span]
430    pub span: Span,
431}
432
433#[derive(Diagnostic)]
434#[diag(attr_parsing_empty_confusables)]
435pub(crate) struct EmptyConfusables {
436    #[primary_span]
437    pub span: Span,
438}
439
440#[derive(Diagnostic)]
441#[help]
442#[diag(attr_parsing_invalid_target)]
443pub(crate) struct InvalidTarget {
444    #[primary_span]
445    #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
446    pub span: Span,
447    pub name: AttrPath,
448    pub target: &'static str,
449    pub applied: DiagArgValue,
450    pub only: &'static str,
451}
452
453#[derive(Diagnostic)]
454#[diag(attr_parsing_invalid_alignment_value, code = E0589)]
455pub(crate) struct InvalidAlignmentValue {
456    #[primary_span]
457    pub span: Span,
458    pub error_part: &'static str,
459}
460
461#[derive(Diagnostic)]
462#[diag(attr_parsing_repr_ident, code = E0565)]
463pub(crate) struct ReprIdent {
464    #[primary_span]
465    pub span: Span,
466}
467
468#[derive(Diagnostic)]
469#[diag(attr_parsing_unrecognized_repr_hint, code = E0552)]
470#[help]
471#[note]
472pub(crate) struct UnrecognizedReprHint {
473    #[primary_span]
474    pub span: Span,
475}
476
477#[derive(Diagnostic)]
478#[diag(attr_parsing_unstable_feature_bound_incompatible_stability)]
479#[help]
480pub(crate) struct UnstableFeatureBoundIncompatibleStability {
481    #[primary_span]
482    pub span: Span,
483}
484
485#[derive(Diagnostic)]
486#[diag(attr_parsing_naked_functions_incompatible_attribute, code = E0736)]
487pub(crate) struct NakedFunctionIncompatibleAttribute {
488    #[primary_span]
489    #[label]
490    pub span: Span,
491    #[label(attr_parsing_naked_attribute)]
492    pub naked_span: Span,
493    pub attr: String,
494}
495
496#[derive(Diagnostic)]
497#[diag(attr_parsing_link_ordinal_out_of_range)]
498#[note]
499pub(crate) struct LinkOrdinalOutOfRange {
500    #[primary_span]
501    pub span: Span,
502    pub ordinal: u128,
503}
504
505#[derive(Diagnostic)]
506#[diag(attr_parsing_rustc_scalable_vector_count_out_of_range)]
507#[note]
508pub(crate) struct RustcScalableVectorCountOutOfRange {
509    #[primary_span]
510    pub span: Span,
511    pub n: u128,
512}
513
514pub(crate) enum AttributeParseErrorReason<'a> {
515    ExpectedNoArgs,
516    ExpectedStringLiteral {
517        byte_string: Option<Span>,
518    },
519    ExpectedIntegerLiteral,
520    ExpectedAtLeastOneArgument,
521    ExpectedSingleArgument,
522    ExpectedList,
523    ExpectedListOrNoArgs,
524    ExpectedListWithNumArgsOrMore {
525        args: usize,
526    },
527    ExpectedNameValueOrNoArgs,
528    ExpectedNonEmptyStringLiteral,
529    UnexpectedLiteral,
530    ExpectedNameValue(Option<Symbol>),
531    DuplicateKey(Symbol),
532    ExpectedSpecificArgument {
533        possibilities: &'a [Symbol],
534        strings: bool,
535        /// Should we tell the user to write a list when they didn't?
536        list: bool,
537    },
538    ExpectedIdentifier,
539}
540
541/// A description of a thing that can be parsed using an attribute parser.
542#[derive(Copy, Clone)]
543pub enum ParsedDescription {
544    /// Used when parsing attributes.
545    Attribute,
546    /// Used when parsing some macros, such as the `cfg!()` macro.
547    Macro,
548}
549
550pub(crate) struct AttributeParseError<'a> {
551    pub(crate) span: Span,
552    pub(crate) attr_span: Span,
553    pub(crate) template: AttributeTemplate,
554    pub(crate) path: AttrPath,
555    pub(crate) description: ParsedDescription,
556    pub(crate) reason: AttributeParseErrorReason<'a>,
557    pub(crate) suggestions: Vec<String>,
558}
559
560impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
561    fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
562        let name = self.path.to_string();
563
564        let description = match self.description {
565            ParsedDescription::Attribute => "attribute",
566            ParsedDescription::Macro => "macro",
567        };
568
569        let mut diag = Diag::new(dcx, level, format!("malformed `{name}` {description} input"));
570        diag.span(self.attr_span);
571        diag.code(E0539);
572        match self.reason {
573            AttributeParseErrorReason::ExpectedStringLiteral { byte_string } => {
574                if let Some(start_point_span) = byte_string {
575                    diag.span_suggestion(
576                        start_point_span,
577                        fluent::attr_parsing_unsupported_literal_suggestion,
578                        "",
579                        Applicability::MaybeIncorrect,
580                    );
581                    diag.note("expected a normal string literal, not a byte string literal");
582
583                    return diag;
584                } else {
585                    diag.span_label(self.span, "expected a string literal here");
586                }
587            }
588            AttributeParseErrorReason::ExpectedIntegerLiteral => {
589                diag.span_label(self.span, "expected an integer literal here");
590            }
591            AttributeParseErrorReason::ExpectedSingleArgument => {
592                diag.span_label(self.span, "expected a single argument here");
593                diag.code(E0805);
594            }
595            AttributeParseErrorReason::ExpectedAtLeastOneArgument => {
596                diag.span_label(self.span, "expected at least 1 argument here");
597            }
598            AttributeParseErrorReason::ExpectedList => {
599                diag.span_label(self.span, "expected this to be a list");
600            }
601            AttributeParseErrorReason::ExpectedListOrNoArgs => {
602                diag.span_label(self.span, "expected a list or no arguments here");
603            }
604            AttributeParseErrorReason::ExpectedListWithNumArgsOrMore { args } => {
605                diag.span_label(self.span, format!("expected {args} or more items"));
606            }
607            AttributeParseErrorReason::ExpectedNameValueOrNoArgs => {
608                diag.span_label(self.span, "didn't expect a list here");
609            }
610            AttributeParseErrorReason::ExpectedNonEmptyStringLiteral => {
611                diag.span_label(self.span, "string is not allowed to be empty");
612            }
613            AttributeParseErrorReason::DuplicateKey(key) => {
614                diag.span_label(self.span, format!("found `{key}` used as a key more than once"));
615                diag.code(E0538);
616            }
617            AttributeParseErrorReason::UnexpectedLiteral => {
618                diag.span_label(self.span, "didn't expect a literal here");
619                diag.code(E0565);
620            }
621            AttributeParseErrorReason::ExpectedNoArgs => {
622                diag.span_label(self.span, "didn't expect any arguments here");
623                diag.code(E0565);
624            }
625            AttributeParseErrorReason::ExpectedNameValue(None) => {
626                // If the span is the entire attribute, the suggestion we add below this match already contains enough information
627                if self.span != self.attr_span {
628                    diag.span_label(
629                        self.span,
630                        format!("expected this to be of the form `... = \"...\"`"),
631                    );
632                }
633            }
634            AttributeParseErrorReason::ExpectedNameValue(Some(name)) => {
635                diag.span_label(
636                    self.span,
637                    format!("expected this to be of the form `{name} = \"...\"`"),
638                );
639            }
640            AttributeParseErrorReason::ExpectedSpecificArgument {
641                possibilities,
642                strings,
643                list: false,
644            } => {
645                let quote = if strings { '"' } else { '`' };
646                match possibilities {
647                    &[] => {}
648                    &[x] => {
649                        diag.span_label(
650                            self.span,
651                            format!("the only valid argument here is {quote}{x}{quote}"),
652                        );
653                    }
654                    [first, second] => {
655                        diag.span_label(self.span, format!("valid arguments are {quote}{first}{quote} or {quote}{second}{quote}"));
656                    }
657                    [first @ .., second_to_last, last] => {
658                        let mut res = String::new();
659                        for i in first {
660                            res.push_str(&format!("{quote}{i}{quote}, "));
661                        }
662                        res.push_str(&format!(
663                            "{quote}{second_to_last}{quote} or {quote}{last}{quote}"
664                        ));
665
666                        diag.span_label(self.span, format!("valid arguments are {res}"));
667                    }
668                }
669            }
670            AttributeParseErrorReason::ExpectedSpecificArgument {
671                possibilities,
672                strings,
673                list: true,
674            } => {
675                let quote = if strings { '"' } else { '`' };
676                match possibilities {
677                    &[] => {}
678                    &[x] => {
679                        diag.span_label(
680                            self.span,
681                            format!(
682                                "this {description} is only valid with {quote}{x}{quote} as an argument"
683                            ),
684                        );
685                    }
686                    [first, second] => {
687                        diag.span_label(self.span, format!("this {description} is only valid with either {quote}{first}{quote} or {quote}{second}{quote} as an argument"));
688                    }
689                    [first @ .., second_to_last, last] => {
690                        let mut res = String::new();
691                        for i in first {
692                            res.push_str(&format!("{quote}{i}{quote}, "));
693                        }
694                        res.push_str(&format!(
695                            "{quote}{second_to_last}{quote} or {quote}{last}{quote}"
696                        ));
697
698                        diag.span_label(self.span, format!("this {description} is only valid with one of the following arguments: {res}"));
699                    }
700                }
701            }
702            AttributeParseErrorReason::ExpectedIdentifier => {
703                diag.span_label(self.span, "expected a valid identifier here");
704            }
705        }
706
707        if let Some(link) = self.template.docs {
708            diag.note(format!("for more information, visit <{link}>"));
709        }
710
711        if self.suggestions.len() < 4 {
712            diag.span_suggestions(
713                self.attr_span,
714                if self.suggestions.len() == 1 {
715                    "must be of the form".to_string()
716                } else {
717                    format!(
718                        "try changing it to one of the following valid forms of the {description}"
719                    )
720                },
721                self.suggestions,
722                Applicability::HasPlaceholders,
723            );
724        }
725
726        diag
727    }
728}
729
730#[derive(Diagnostic)]
731#[diag(attr_parsing_invalid_attr_unsafe)]
732#[note]
733pub(crate) struct InvalidAttrUnsafe {
734    #[primary_span]
735    #[label]
736    pub span: Span,
737    pub name: AttrPath,
738}
739
740#[derive(Diagnostic)]
741#[diag(attr_parsing_unsafe_attr_outside_unsafe)]
742pub(crate) struct UnsafeAttrOutsideUnsafe {
743    #[primary_span]
744    #[label]
745    pub span: Span,
746    #[subdiagnostic]
747    pub suggestion: Option<UnsafeAttrOutsideUnsafeSuggestion>,
748}
749
750#[derive(Subdiagnostic)]
751#[multipart_suggestion(
752    attr_parsing_unsafe_attr_outside_unsafe_suggestion,
753    applicability = "machine-applicable"
754)]
755pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion {
756    #[suggestion_part(code = "unsafe(")]
757    pub left: Span,
758    #[suggestion_part(code = ")")]
759    pub right: Span,
760}
761
762#[derive(Diagnostic)]
763#[diag(attr_parsing_meta_bad_delim)]
764pub(crate) struct MetaBadDelim {
765    #[primary_span]
766    pub span: Span,
767    #[subdiagnostic]
768    pub sugg: MetaBadDelimSugg,
769}
770
771#[derive(Subdiagnostic)]
772#[multipart_suggestion(
773    attr_parsing_meta_bad_delim_suggestion,
774    applicability = "machine-applicable"
775)]
776pub(crate) struct MetaBadDelimSugg {
777    #[suggestion_part(code = "(")]
778    pub open: Span,
779    #[suggestion_part(code = ")")]
780    pub close: Span,
781}
782
783#[derive(Diagnostic)]
784#[diag(attr_parsing_invalid_meta_item)]
785pub(crate) struct InvalidMetaItem {
786    #[primary_span]
787    pub span: Span,
788    pub descr: String,
789    #[subdiagnostic]
790    pub quote_ident_sugg: Option<InvalidMetaItemQuoteIdentSugg>,
791    #[subdiagnostic]
792    pub remove_neg_sugg: Option<InvalidMetaItemRemoveNegSugg>,
793    #[label]
794    pub label: Option<Span>,
795}
796
797#[derive(Subdiagnostic)]
798#[multipart_suggestion(attr_parsing_quote_ident_sugg, applicability = "machine-applicable")]
799pub(crate) struct InvalidMetaItemQuoteIdentSugg {
800    #[suggestion_part(code = "\"")]
801    pub before: Span,
802    #[suggestion_part(code = "\"")]
803    pub after: Span,
804}
805
806#[derive(Subdiagnostic)]
807#[multipart_suggestion(attr_parsing_remove_neg_sugg, applicability = "machine-applicable")]
808pub(crate) struct InvalidMetaItemRemoveNegSugg {
809    #[suggestion_part(code = "")]
810    pub negative_sign: Span,
811}
812
813#[derive(Diagnostic)]
814#[diag(attr_parsing_suffixed_literal_in_attribute)]
815#[help]
816pub(crate) struct SuffixedLiteralInAttribute {
817    #[primary_span]
818    pub span: Span,
819}
820
821#[derive(Diagnostic)]
822#[diag(attr_parsing_empty_link_name, code = E0454)]
823pub(crate) struct EmptyLinkName {
824    #[primary_span]
825    #[label]
826    pub span: Span,
827}
828
829#[derive(Diagnostic)]
830#[diag(attr_parsing_link_framework_apple, code = E0455)]
831pub(crate) struct LinkFrameworkApple {
832    #[primary_span]
833    pub span: Span,
834}
835
836#[derive(Diagnostic)]
837#[diag(attr_parsing_incompatible_wasm_link)]
838pub(crate) struct IncompatibleWasmLink {
839    #[primary_span]
840    pub span: Span,
841}
842
843#[derive(Diagnostic)]
844#[diag(attr_parsing_link_requires_name, code = E0459)]
845pub(crate) struct LinkRequiresName {
846    #[primary_span]
847    #[label]
848    pub span: Span,
849}
850
851#[derive(Diagnostic)]
852#[diag(attr_parsing_raw_dylib_no_nul)]
853pub(crate) struct RawDylibNoNul {
854    #[primary_span]
855    pub span: Span,
856}
857
858#[derive(Diagnostic)]
859#[diag(attr_parsing_raw_dylib_only_windows, code = E0455)]
860pub(crate) struct RawDylibOnlyWindows {
861    #[primary_span]
862    pub span: Span,
863}
864
865#[derive(Diagnostic)]
866#[diag(attr_parsing_invalid_link_modifier)]
867pub(crate) struct InvalidLinkModifier {
868    #[primary_span]
869    pub span: Span,
870}
871
872#[derive(Diagnostic)]
873#[diag(attr_parsing_multiple_modifiers)]
874pub(crate) struct MultipleModifiers {
875    #[primary_span]
876    pub span: Span,
877    pub modifier: Symbol,
878}
879
880#[derive(Diagnostic)]
881#[diag(attr_parsing_import_name_type_x86)]
882pub(crate) struct ImportNameTypeX86 {
883    #[primary_span]
884    pub span: Span,
885}
886
887#[derive(Diagnostic)]
888#[diag(attr_parsing_bundle_needs_static)]
889pub(crate) struct BundleNeedsStatic {
890    #[primary_span]
891    pub span: Span,
892}
893
894#[derive(Diagnostic)]
895#[diag(attr_parsing_whole_archive_needs_static)]
896pub(crate) struct WholeArchiveNeedsStatic {
897    #[primary_span]
898    pub span: Span,
899}
900
901#[derive(Diagnostic)]
902#[diag(attr_parsing_as_needed_compatibility)]
903pub(crate) struct AsNeededCompatibility {
904    #[primary_span]
905    pub span: Span,
906}
907
908#[derive(Diagnostic)]
909#[diag(attr_parsing_import_name_type_raw)]
910pub(crate) struct ImportNameTypeRaw {
911    #[primary_span]
912    pub span: Span,
913}
914
915#[derive(Diagnostic)]
916#[diag(attr_parsing_limit_invalid)]
917pub(crate) struct LimitInvalid<'a> {
918    #[primary_span]
919    pub span: Span,
920    #[label]
921    pub value_span: Span,
922    pub error_str: &'a str,
923}
924
925#[derive(Diagnostic)]
926#[diag(attr_parsing_cfg_attr_bad_delim)]
927pub(crate) struct CfgAttrBadDelim {
928    #[primary_span]
929    pub span: Span,
930    #[subdiagnostic]
931    pub sugg: MetaBadDelimSugg,
932}
933
934#[derive(Diagnostic)]
935#[diag(attr_parsing_doc_alias_malformed)]
936pub(crate) struct DocAliasMalformed {
937    #[primary_span]
938    pub span: Span,
939}
940
941#[derive(Diagnostic)]
942#[diag(attr_parsing_unsupported_instruction_set)]
943pub(crate) struct UnsupportedInstructionSet<'a> {
944    #[primary_span]
945    pub span: Span,
946    pub instruction_set: Symbol,
947    pub current_target: &'a TargetTuple,
948}