@@ -587,7 +587,9 @@ pub(crate) struct LinkOrdinalOutOfRange {
587587}
588588
589589pub ( crate ) enum AttributeParseErrorReason < ' a > {
590- ExpectedNoArgs ,
590+ ExpectedNoArgs {
591+ path : & ' a AttrPath ,
592+ } ,
591593 ExpectedStringLiteral {
592594 byte_string : Option < Span > ,
593595 } ,
@@ -619,13 +621,28 @@ pub(crate) struct AttributeParseError<'a> {
619621 pub ( crate ) reason : AttributeParseErrorReason < ' a > ,
620622}
621623
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+
622636impl < ' a , G : EmissionGuarantee > Diagnostic < ' a , G > for AttributeParseError < ' _ > {
623637 fn into_diag ( self , dcx : DiagCtxtHandle < ' a > , level : Level ) -> Diag < ' a , G > {
624638 let name = self . attribute . to_string ( ) ;
625639
626640 let mut diag = Diag :: new ( dcx, level, format ! ( "malformed `{name}` attribute input" ) ) ;
627641 diag. span ( self . attr_span ) ;
628642 diag. code ( E0539 ) ;
643+
644+ let mut show_default_suggestions = DefaultSuggestionStyle :: Suggestion ;
645+
629646 match self . reason {
630647 AttributeParseErrorReason :: ExpectedStringLiteral { byte_string } => {
631648 if let Some ( start_point_span) = byte_string {
@@ -637,7 +654,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
637654 ) ;
638655 diag. note ( "expected a normal string literal, not a byte string literal" ) ;
639656
640- return diag ;
657+ show_default_suggestions = DefaultSuggestionStyle :: None ;
641658 } else {
642659 diag. span_label ( self . span , "expected a string literal here" ) ;
643660 }
@@ -663,9 +680,19 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for AttributeParseError<'_> {
663680 diag. span_label ( self . span , "didn't expect a literal here" ) ;
664681 diag. code ( E0565 ) ;
665682 }
666- AttributeParseErrorReason :: ExpectedNoArgs => {
683+ AttributeParseErrorReason :: ExpectedNoArgs { path } => {
667684 diag. span_label ( self . span , "didn't expect any arguments here" ) ;
668685 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+ }
669696 }
670697 AttributeParseErrorReason :: ExpectedNameValue ( None ) => {
671698 // 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<'_> {
756783 if let Some ( link) = self . template . docs {
757784 diag. note ( format ! ( "for more information, visit <{link}>" ) ) ;
758785 }
786+
759787 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+ } ;
760805
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 ) ;
771807
772808 diag
773809 }
0 commit comments