@@ -6408,41 +6408,52 @@ impl<'a> Parser<'a> {
6408
6408
}
6409
6409
}
6410
6410
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
+
6411
6442
/// Given a termination token, parse all of the items in a module
6412
6443
fn parse_mod_items ( & mut self , term : & token:: Token , inner_lo : Span ) -> PResult < ' a , Mod > {
6413
6444
let mut items = vec ! [ ] ;
6414
6445
while let Some ( item) = self . parse_item ( ) ? {
6415
6446
items. push ( item) ;
6447
+ self . maybe_consume_incorrect_semicolon ( & items) ;
6416
6448
}
6417
6449
6418
6450
if !self . eat ( term) {
6419
6451
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) ) ;
6443
6454
err. span_label ( self . span , "expected item" ) ;
6455
+ return Err ( err) ;
6444
6456
}
6445
- return Err ( err) ;
6446
6457
}
6447
6458
6448
6459
let hi = if self . span . is_dummy ( ) {
0 commit comments