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