@@ -587,7 +587,9 @@ pub(crate) struct LinkOrdinalOutOfRange {
587
587
}
588
588
589
589
pub ( crate ) enum AttributeParseErrorReason < ' a > {
590
- ExpectedNoArgs ,
590
+ ExpectedNoArgs {
591
+ path : & ' a AttrPath ,
592
+ } ,
591
593
ExpectedStringLiteral {
592
594
byte_string : Option < Span > ,
593
595
} ,
@@ -619,13 +621,28 @@ pub(crate) struct AttributeParseError<'a> {
619
621
pub ( crate ) reason : AttributeParseErrorReason < ' a > ,
620
622
}
621
623
624
+ /// based on the attribute's template we add relevant suggestions to the error automatically.
625
+ enum DefaultSuggestionStyle {
626
+ /// give a hint about the valid forms of the attribute.
627
+ /// Useful if there's already a better suggestion given than the automatic ones can provide
628
+ /// but we'd still like to show which syntax forms are valid.
629
+ Hint ,
630
+ /// Use the template to suggest changes to the attribute
631
+ Suggestion ,
632
+ /// Don't show any default suggestions
633
+ None ,
634
+ }
635
+
622
636
impl < ' a , G : EmissionGuarantee > Diagnostic < ' a , G > for AttributeParseError < ' _ > {
623
637
fn into_diag ( self , dcx : DiagCtxtHandle < ' a > , level : Level ) -> Diag < ' a , G > {
624
638
let name = self . attribute . to_string ( ) ;
625
639
626
640
let mut diag = Diag :: new ( dcx, level, format ! ( "malformed `{name}` attribute input" ) ) ;
627
641
diag. span ( self . attr_span ) ;
628
642
diag. code ( E0539 ) ;
643
+
644
+ let mut show_default_suggestions = DefaultSuggestionStyle :: Suggestion ;
645
+
629
646
match self . reason {
630
647
AttributeParseErrorReason :: ExpectedStringLiteral { byte_string } => {
631
648
if let Some ( start_point_span) = byte_string {
@@ -637,7 +654,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
637
654
) ;
638
655
diag. note ( "expected a normal string literal, not a byte string literal" ) ;
639
656
640
- return diag ;
657
+ show_default_suggestions = DefaultSuggestionStyle :: None ;
641
658
} else {
642
659
diag. span_label ( self . span , "expected a string literal here" ) ;
643
660
}
@@ -663,9 +680,19 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
663
680
diag. span_label ( self . span , "didn't expect a literal here" ) ;
664
681
diag. code ( E0565 ) ;
665
682
}
666
- AttributeParseErrorReason :: ExpectedNoArgs => {
683
+ AttributeParseErrorReason :: ExpectedNoArgs { path } => {
667
684
diag. span_label ( self . span , "didn't expect any arguments here" ) ;
668
685
diag. code ( E0565 ) ;
686
+
687
+ if path. span != self . attribute . span {
688
+ diag. span_suggestion (
689
+ path. span . to ( self . span ) ,
690
+ "remove this argument" ,
691
+ path,
692
+ Applicability :: MachineApplicable ,
693
+ ) ;
694
+ show_default_suggestions = DefaultSuggestionStyle :: Hint ;
695
+ }
669
696
}
670
697
AttributeParseErrorReason :: ExpectedNameValue ( None ) => {
671
698
// If the span is the entire attribute, the suggestion we add below this match already contains enough information
@@ -756,18 +783,27 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
756
783
if let Some ( link) = self . template . docs {
757
784
diag. note ( format ! ( "for more information, visit <{link}>" ) ) ;
758
785
}
786
+
759
787
let suggestions = self . template . suggestions ( self . attr_style , & name) ;
788
+ let text = match show_default_suggestions {
789
+ DefaultSuggestionStyle :: Hint => {
790
+ if suggestions. len ( ) == 1 {
791
+ "the only valid form of the attribute is"
792
+ } else {
793
+ "these are the valid forms of the attribute"
794
+ }
795
+ }
796
+ DefaultSuggestionStyle :: Suggestion => {
797
+ if suggestions. len ( ) == 1 {
798
+ "must be of the form"
799
+ } else {
800
+ "try changing it to one of the following valid forms of the attribute"
801
+ }
802
+ }
803
+ DefaultSuggestionStyle :: None => return diag,
804
+ } ;
760
805
761
- diag. span_suggestions (
762
- self . attr_span ,
763
- if suggestions. len ( ) == 1 {
764
- "must be of the form"
765
- } else {
766
- "try changing it to one of the following valid forms of the attribute"
767
- } ,
768
- suggestions,
769
- Applicability :: HasPlaceholders ,
770
- ) ;
806
+ diag. span_suggestions ( self . attr_span , text, suggestions, Applicability :: HasPlaceholders ) ;
771
807
772
808
diag
773
809
}
0 commit comments