@@ -1524,7 +1524,7 @@ impl<'a> Parser<'a> {
15241524 at_end : & mut bool ,
15251525 mut attrs : Vec < Attribute > ) -> PResult < ' a , TraitItem > {
15261526 let lo = self . span ;
1527-
1527+ self . eat_bad_pub ( ) ;
15281528 let ( name, node, generics) = if self . eat_keyword ( keywords:: Type ) {
15291529 self . parse_trait_item_assoc_ty ( ) ?
15301530 } else if self . is_const_item ( ) {
@@ -7688,6 +7688,7 @@ impl<'a> Parser<'a> {
76887688
76897689 let struct_def;
76907690 let mut disr_expr = None ;
7691+ self . eat_bad_pub ( ) ;
76917692 let ident = self . parse_ident ( ) ?;
76927693 if self . check ( & token:: OpenDelim ( token:: Brace ) ) {
76937694 // Parse a struct variant.
@@ -7719,11 +7720,25 @@ impl<'a> Parser<'a> {
77197720 } ;
77207721 variants. push ( respan ( vlo. to ( self . prev_span ) , vr) ) ;
77217722
7722- if !self . eat ( & token:: Comma ) { break ; }
7723+ if !self . eat ( & token:: Comma ) {
7724+ if self . token . is_ident ( ) && !self . token . is_reserved_ident ( ) {
7725+ let sp = self . sess . source_map ( ) . next_point ( self . prev_span ) ;
7726+ let mut err = self . struct_span_err ( sp, "missing comma" ) ;
7727+ err. span_suggestion_short (
7728+ sp,
7729+ "missing comma" ,
7730+ "," . to_owned ( ) ,
7731+ Applicability :: MaybeIncorrect ,
7732+ ) ;
7733+ err. emit ( ) ;
7734+ } else {
7735+ break ;
7736+ }
7737+ }
77237738 }
77247739 self . expect ( & token:: CloseDelim ( token:: Brace ) ) ?;
77257740 if !any_disr. is_empty ( ) && !all_nullary {
7726- let mut err =self . struct_span_err (
7741+ let mut err = self . struct_span_err (
77277742 any_disr. clone ( ) ,
77287743 "discriminator values can only be used with a field-less enum" ,
77297744 ) ;
@@ -8608,6 +8623,21 @@ impl<'a> Parser<'a> {
86088623 Applicability :: MaybeIncorrect ,
86098624 ) . emit ( ) ;
86108625 }
8626+
8627+ /// Recover from `pub` keyword in places where it seems _reasonable_ but isn't valid.
8628+ fn eat_bad_pub ( & mut self ) {
8629+ if self . token . is_keyword ( keywords:: Pub ) {
8630+ match self . parse_visibility ( false ) {
8631+ Ok ( vis) => {
8632+ let mut err = self . diagnostic ( )
8633+ . struct_span_err ( vis. span , "unnecessary visibility qualifier" ) ;
8634+ err. span_label ( vis. span , "`pub` not permitted here" ) ;
8635+ err. emit ( ) ;
8636+ }
8637+ Err ( mut err) => err. emit ( ) ,
8638+ }
8639+ }
8640+ }
86118641}
86128642
86138643pub fn emit_unclosed_delims ( unclosed_delims : & mut Vec < UnmatchedBrace > , handler : & errors:: Handler ) {
0 commit comments