@@ -6482,41 +6482,52 @@ impl<'a> Parser<'a> {
64826482 }
64836483 }
64846484
6485+ fn maybe_consume_incorrect_semicolon ( & mut self , items : & [ P < Item > ] ) -> bool {
6486+ if self . eat ( & token:: Semi ) {
6487+ let mut err = self . struct_span_err ( self . prev_span , "expected item, found `;`" ) ;
6488+ err. span_suggestion_short_with_applicability (
6489+ self . prev_span ,
6490+ "remove this semicolon" ,
6491+ String :: new ( ) ,
6492+ Applicability :: MachineApplicable ,
6493+ ) ;
6494+ if !items. is_empty ( ) {
6495+ let previous_item = & items[ items. len ( ) -1 ] ;
6496+ let previous_item_kind_name = match previous_item. node {
6497+ // say "braced struct" because tuple-structs and
6498+ // braceless-empty-struct declarations do take a semicolon
6499+ ItemKind :: Struct ( ..) => Some ( "braced struct" ) ,
6500+ ItemKind :: Enum ( ..) => Some ( "enum" ) ,
6501+ ItemKind :: Trait ( ..) => Some ( "trait" ) ,
6502+ ItemKind :: Union ( ..) => Some ( "union" ) ,
6503+ _ => None ,
6504+ } ;
6505+ if let Some ( name) = previous_item_kind_name {
6506+ err. help ( & format ! ( "{} declarations are not followed by a semicolon" , name) ) ;
6507+ }
6508+ }
6509+ err. emit ( ) ;
6510+ true
6511+ } else {
6512+ false
6513+ }
6514+ }
6515+
64856516 /// Given a termination token, parse all of the items in a module
64866517 fn parse_mod_items ( & mut self , term : & token:: Token , inner_lo : Span ) -> PResult < ' a , Mod > {
64876518 let mut items = vec ! [ ] ;
64886519 while let Some ( item) = self . parse_item ( ) ? {
64896520 items. push ( item) ;
6521+ self . maybe_consume_incorrect_semicolon ( & items) ;
64906522 }
64916523
64926524 if !self . eat ( term) {
64936525 let token_str = self . this_token_descr ( ) ;
6494- let mut err = self . fatal ( & format ! ( "expected item, found {}" , token_str) ) ;
6495- if self . token == token:: Semi {
6496- let msg = "consider removing this semicolon" ;
6497- err. span_suggestion_short_with_applicability (
6498- self . span , msg, String :: new ( ) , Applicability :: MachineApplicable
6499- ) ;
6500- if !items. is_empty ( ) { // Issue #51603
6501- let previous_item = & items[ items. len ( ) -1 ] ;
6502- let previous_item_kind_name = match previous_item. node {
6503- // say "braced struct" because tuple-structs and
6504- // braceless-empty-struct declarations do take a semicolon
6505- ItemKind :: Struct ( ..) => Some ( "braced struct" ) ,
6506- ItemKind :: Enum ( ..) => Some ( "enum" ) ,
6507- ItemKind :: Trait ( ..) => Some ( "trait" ) ,
6508- ItemKind :: Union ( ..) => Some ( "union" ) ,
6509- _ => None ,
6510- } ;
6511- if let Some ( name) = previous_item_kind_name {
6512- err. help ( & format ! ( "{} declarations are not followed by a semicolon" ,
6513- name) ) ;
6514- }
6515- }
6516- } else {
6526+ if !self . maybe_consume_incorrect_semicolon ( & items) {
6527+ let mut err = self . fatal ( & format ! ( "expected item, found {}" , token_str) ) ;
65176528 err. span_label ( self . span , "expected item" ) ;
6529+ return Err ( err) ;
65186530 }
6519- return Err ( err) ;
65206531 }
65216532
65226533 let hi = if self . span . is_dummy ( ) {
0 commit comments