@@ -6408,41 +6408,52 @@ impl<'a> Parser<'a> {
64086408 }
64096409 }
64106410
6411+ fn maybe_consume_incorrect_semicolon ( & mut self , items : & [ P < Item > ] ) -> bool {
6412+ if self . eat ( & token:: Semi ) {
6413+ let mut err = self . struct_span_err ( self . prev_span , "expected item, found `;`" ) ;
6414+ err. span_suggestion_short_with_applicability (
6415+ self . prev_span ,
6416+ "remove this semicolon" ,
6417+ String :: new ( ) ,
6418+ Applicability :: MachineApplicable ,
6419+ ) ;
6420+ if !items. is_empty ( ) {
6421+ let previous_item = & items[ items. len ( ) -1 ] ;
6422+ let previous_item_kind_name = match previous_item. node {
6423+ // say "braced struct" because tuple-structs and
6424+ // braceless-empty-struct declarations do take a semicolon
6425+ ItemKind :: Struct ( ..) => Some ( "braced struct" ) ,
6426+ ItemKind :: Enum ( ..) => Some ( "enum" ) ,
6427+ ItemKind :: Trait ( ..) => Some ( "trait" ) ,
6428+ ItemKind :: Union ( ..) => Some ( "union" ) ,
6429+ _ => None ,
6430+ } ;
6431+ if let Some ( name) = previous_item_kind_name {
6432+ err. help ( & format ! ( "{} declarations are not followed by a semicolon" , name) ) ;
6433+ }
6434+ }
6435+ err. emit ( ) ;
6436+ true
6437+ } else {
6438+ false
6439+ }
6440+ }
6441+
64116442 /// Given a termination token, parse all of the items in a module
64126443 fn parse_mod_items ( & mut self , term : & token:: Token , inner_lo : Span ) -> PResult < ' a , Mod > {
64136444 let mut items = vec ! [ ] ;
64146445 while let Some ( item) = self . parse_item ( ) ? {
64156446 items. push ( item) ;
6447+ self . maybe_consume_incorrect_semicolon ( & items) ;
64166448 }
64176449
64186450 if !self . eat ( term) {
64196451 let token_str = self . this_token_descr ( ) ;
6420- let mut err = self . fatal ( & format ! ( "expected item, found {}" , token_str) ) ;
6421- if self . token == token:: Semi {
6422- let msg = "consider removing this semicolon" ;
6423- err. span_suggestion_short_with_applicability (
6424- self . span , msg, String :: new ( ) , Applicability :: MachineApplicable
6425- ) ;
6426- if !items. is_empty ( ) { // Issue #51603
6427- let previous_item = & items[ items. len ( ) -1 ] ;
6428- let previous_item_kind_name = match previous_item. node {
6429- // say "braced struct" because tuple-structs and
6430- // braceless-empty-struct declarations do take a semicolon
6431- ItemKind :: Struct ( ..) => Some ( "braced struct" ) ,
6432- ItemKind :: Enum ( ..) => Some ( "enum" ) ,
6433- ItemKind :: Trait ( ..) => Some ( "trait" ) ,
6434- ItemKind :: Union ( ..) => Some ( "union" ) ,
6435- _ => None ,
6436- } ;
6437- if let Some ( name) = previous_item_kind_name {
6438- err. help ( & format ! ( "{} declarations are not followed by a semicolon" ,
6439- name) ) ;
6440- }
6441- }
6442- } else {
6452+ if !self . maybe_consume_incorrect_semicolon ( & items) {
6453+ let mut err = self . fatal ( & format ! ( "expected item, found {}" , token_str) ) ;
64436454 err. span_label ( self . span , "expected item" ) ;
6455+ return Err ( err) ;
64446456 }
6445- return Err ( err) ;
64466457 }
64476458
64486459 let hi = if self . span . is_dummy ( ) {
0 commit comments