99use rustc_ast:: ast:: * ;
1010use rustc_ast:: attr;
1111use rustc_ast:: expand:: is_proc_macro_attr;
12+ use rustc_ast:: ptr:: P ;
1213use rustc_ast:: visit:: { self , AssocCtxt , FnCtxt , FnKind , Visitor } ;
1314use rustc_ast:: walk_list;
1415use rustc_ast_pretty:: pprust;
@@ -594,6 +595,54 @@ impl<'a> AstValidator<'a> {
594595 . span_label ( ident. span , format ! ( "`_` is not a valid name for this `{}` item" , kind) )
595596 . emit ( ) ;
596597 }
598+
599+ fn deny_generic_params ( & self , generics : & Generics , ident_span : Span ) {
600+ if !generics. params . is_empty ( ) {
601+ struct_span_err ! (
602+ self . session,
603+ generics. span,
604+ E0567 ,
605+ "auto traits cannot have generic parameters"
606+ )
607+ . span_label ( ident_span, "auto trait cannot have generic parameters" )
608+ . span_suggestion (
609+ generics. span ,
610+ "remove the parameters" ,
611+ String :: new ( ) ,
612+ Applicability :: MachineApplicable ,
613+ )
614+ . emit ( ) ;
615+ }
616+ }
617+
618+ fn deny_super_traits ( & self , bounds : & GenericBounds , ident_span : Span ) {
619+ if let [ first @ last] | [ first, .., last] = & bounds[ ..] {
620+ let span = first. span ( ) . to ( last. span ( ) ) ;
621+ struct_span_err ! ( self . session, span, E0568 , "auto traits cannot have super traits" )
622+ . span_label ( ident_span, "auto trait cannot have super traits" )
623+ . span_suggestion (
624+ span,
625+ "remove the super traits" ,
626+ String :: new ( ) ,
627+ Applicability :: MachineApplicable ,
628+ )
629+ . emit ( ) ;
630+ }
631+ }
632+
633+ fn deny_items ( & self , trait_items : & [ P < AssocItem > ] , ident_span : Span ) {
634+ if !trait_items. is_empty ( ) {
635+ let spans: Vec < _ > = trait_items. iter ( ) . map ( |i| i. ident . span ) . collect ( ) ;
636+ struct_span_err ! (
637+ self . session,
638+ spans,
639+ E0380 ,
640+ "auto traits cannot have methods or associated items"
641+ )
642+ . span_label ( ident_span, "auto trait cannot have items" )
643+ . emit ( ) ;
644+ }
645+ }
597646}
598647
599648fn validate_generic_param_order < ' a > (
@@ -779,7 +828,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
779828 defaultness : _,
780829 constness : _,
781830 generics : _,
782- of_trait : Some ( _ ) ,
831+ of_trait : Some ( ref t ) ,
783832 ref self_ty,
784833 items : _,
785834 } => {
@@ -794,13 +843,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
794843 . help ( "use `auto trait Trait {}` instead" )
795844 . emit ( ) ;
796845 }
797- if let ( Unsafe :: Yes ( span) , ImplPolarity :: Negative ) = ( unsafety, polarity) {
846+ if let ( Unsafe :: Yes ( span) , ImplPolarity :: Negative ( sp ) ) = ( unsafety, polarity) {
798847 struct_span_err ! (
799848 this. session,
800- item . span,
849+ sp . to ( t . path . span) ,
801850 E0198 ,
802851 "negative impls cannot be unsafe"
803852 )
853+ . span_label ( sp, "negative because of this" )
804854 . span_label ( span, "unsafe because of this" )
805855 . emit ( ) ;
806856 }
@@ -816,38 +866,36 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
816866 constness,
817867 generics : _,
818868 of_trait : None ,
819- self_ty : _ ,
869+ ref self_ty ,
820870 items : _,
821871 } => {
872+ let error = |annotation_span, annotation| {
873+ let mut err = self . err_handler ( ) . struct_span_err (
874+ self_ty. span ,
875+ & format ! ( "inherent impls cannot be {}" , annotation) ,
876+ ) ;
877+ err. span_label ( annotation_span, & format ! ( "{} because of this" , annotation) ) ;
878+ err. span_label ( self_ty. span , "inherent impl for this type" ) ;
879+ err
880+ } ;
881+
822882 self . invalid_visibility (
823883 & item. vis ,
824884 Some ( "place qualifiers on individual impl items instead" ) ,
825885 ) ;
826886 if let Unsafe :: Yes ( span) = unsafety {
827- struct_span_err ! (
828- self . session,
829- item. span,
830- E0197 ,
831- "inherent impls cannot be unsafe"
832- )
833- . span_label ( span, "unsafe because of this" )
834- . emit ( ) ;
887+ error ( span, "unsafe" ) . code ( error_code ! ( E0197 ) ) . emit ( ) ;
835888 }
836- if polarity == ImplPolarity :: Negative {
837- self . err_handler ( ) . span_err ( item . span , "inherent impls cannot be negative" ) ;
889+ if let ImplPolarity :: Negative ( span ) = polarity {
890+ error ( span, "negative" ) . emit ( ) ;
838891 }
839892 if let Defaultness :: Default ( def_span) = defaultness {
840- let span = self . session . source_map ( ) . def_span ( item. span ) ;
841- self . err_handler ( )
842- . struct_span_err ( span, "inherent impls cannot be `default`" )
843- . span_label ( def_span, "`default` because of this" )
893+ error ( def_span, "`default`" )
844894 . note ( "only trait implementations may be annotated with `default`" )
845895 . emit ( ) ;
846896 }
847897 if let Const :: Yes ( span) = constness {
848- self . err_handler ( )
849- . struct_span_err ( item. span , "inherent impls cannot be `const`" )
850- . span_label ( span, "`const` because of this" )
898+ error ( span, "`const`" )
851899 . note ( "only trait implementations may be annotated with `const`" )
852900 . emit ( ) ;
853901 }
@@ -882,33 +930,9 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
882930 ItemKind :: Trait ( is_auto, _, ref generics, ref bounds, ref trait_items) => {
883931 if is_auto == IsAuto :: Yes {
884932 // Auto traits cannot have generics, super traits nor contain items.
885- if !generics. params . is_empty ( ) {
886- struct_span_err ! (
887- self . session,
888- item. span,
889- E0567 ,
890- "auto traits cannot have generic parameters"
891- )
892- . emit ( ) ;
893- }
894- if !bounds. is_empty ( ) {
895- struct_span_err ! (
896- self . session,
897- item. span,
898- E0568 ,
899- "auto traits cannot have super traits"
900- )
901- . emit ( ) ;
902- }
903- if !trait_items. is_empty ( ) {
904- struct_span_err ! (
905- self . session,
906- item. span,
907- E0380 ,
908- "auto traits cannot have methods or associated items"
909- )
910- . emit ( ) ;
911- }
933+ self . deny_generic_params ( generics, item. ident . span ) ;
934+ self . deny_super_traits ( bounds, item. ident . span ) ;
935+ self . deny_items ( trait_items, item. ident . span ) ;
912936 }
913937 self . no_questions_in_bounds ( bounds, "supertraits" , true ) ;
914938
@@ -1153,9 +1177,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
11531177 } ) = fk. header ( )
11541178 {
11551179 self . err_handler ( )
1156- . struct_span_err ( span, "functions cannot be both `const` and `async`" )
1180+ . struct_span_err (
1181+ vec ! [ * cspan, * aspan] ,
1182+ "functions cannot be both `const` and `async`" ,
1183+ )
11571184 . span_label ( * cspan, "`const` because of this" )
11581185 . span_label ( * aspan, "`async` because of this" )
1186+ . span_label ( span, "" ) // Point at the fn header.
11591187 . emit ( ) ;
11601188 }
11611189
0 commit comments