@@ -3480,32 +3480,22 @@ impl<'a> Parser<'a> {
3480
3480
} )
3481
3481
}
3482
3482
3483
- /// Get an expected item after attributes error message.
3484
- fn expected_item_err ( attrs : & [ Attribute ] ) -> & ' static str {
3485
- match attrs. last ( ) {
3486
- Some ( & Attribute { node : ast:: Attribute_ { is_sugared_doc : true , .. } , .. } ) => {
3487
- "expected item after doc comment"
3488
- }
3489
- _ => "expected item after attributes" ,
3490
- }
3491
- }
3492
-
3493
3483
/// Parse a statement. may include decl.
3494
3484
/// Precondition: any attributes are parsed already
3495
3485
pub fn parse_stmt ( & mut self , item_attrs : Vec < Attribute > ) -> P < Stmt > {
3496
3486
maybe_whole ! ( self , NtStmt ) ;
3497
3487
3498
- fn check_expected_item ( p : & mut Parser , attrs : & [ Attribute ] ) {
3488
+ fn check_expected_item ( p : & mut Parser , found_attrs : bool ) {
3499
3489
// If we have attributes then we should have an item
3500
- if !attrs . is_empty ( ) {
3490
+ if found_attrs {
3501
3491
let last_span = p. last_span ;
3502
- p. span_err ( last_span, Parser :: expected_item_err ( attrs ) ) ;
3492
+ p. span_err ( last_span, "expected item after attributes" ) ;
3503
3493
}
3504
3494
}
3505
3495
3506
3496
let lo = self . span . lo ;
3507
3497
if self . is_keyword ( keywords:: Let ) {
3508
- check_expected_item ( self , item_attrs. as_slice ( ) ) ;
3498
+ check_expected_item ( self , ! item_attrs. is_empty ( ) ) ;
3509
3499
self . expect_keyword ( keywords:: Let ) ;
3510
3500
let decl = self . parse_let ( ) ;
3511
3501
P ( spanned ( lo, decl. span . hi , StmtDecl ( decl, ast:: DUMMY_NODE_ID ) ) )
@@ -3514,7 +3504,7 @@ impl<'a> Parser<'a> {
3514
3504
&& self . look_ahead ( 1 , |t| * t == token:: NOT ) {
3515
3505
// it's a macro invocation:
3516
3506
3517
- check_expected_item ( self , item_attrs. as_slice ( ) ) ;
3507
+ check_expected_item ( self , ! item_attrs. is_empty ( ) ) ;
3518
3508
3519
3509
// Potential trouble: if we allow macros with paths instead of
3520
3510
// idents, we'd need to look ahead past the whole path here...
@@ -3571,7 +3561,6 @@ impl<'a> Parser<'a> {
3571
3561
3572
3562
} else {
3573
3563
let found_attrs = !item_attrs. is_empty ( ) ;
3574
- let item_err = Parser :: expected_item_err ( item_attrs. as_slice ( ) ) ;
3575
3564
match self . parse_item_or_view_item ( item_attrs, false ) {
3576
3565
IoviItem ( i) => {
3577
3566
let hi = i. span . hi ;
@@ -3586,10 +3575,7 @@ impl<'a> Parser<'a> {
3586
3575
self . fatal ( "foreign items are not allowed here" ) ;
3587
3576
}
3588
3577
IoviNone ( _) => {
3589
- if found_attrs {
3590
- let last_span = self . last_span ;
3591
- self . span_err ( last_span, item_err) ;
3592
- }
3578
+ check_expected_item ( self , found_attrs) ;
3593
3579
3594
3580
// Remainder are line-expr stmts.
3595
3581
let e = self . parse_expr_res ( RestrictionStmtExpr ) ;
@@ -3667,8 +3653,7 @@ impl<'a> Parser<'a> {
3667
3653
token:: SEMI => {
3668
3654
if !attributes_box. is_empty ( ) {
3669
3655
let last_span = self . last_span ;
3670
- self . span_err ( last_span,
3671
- Parser :: expected_item_err ( attributes_box. as_slice ( ) ) ) ;
3656
+ self . span_err ( last_span, "expected item after attributes" ) ;
3672
3657
attributes_box = Vec :: new ( ) ;
3673
3658
}
3674
3659
self . bump ( ) ; // empty
@@ -3754,8 +3739,7 @@ impl<'a> Parser<'a> {
3754
3739
3755
3740
if !attributes_box. is_empty ( ) {
3756
3741
let last_span = self . last_span ;
3757
- self . span_err ( last_span,
3758
- Parser :: expected_item_err ( attributes_box. as_slice ( ) ) ) ;
3742
+ self . span_err ( last_span, "expected item after attributes" ) ;
3759
3743
}
3760
3744
3761
3745
let hi = self . span . hi ;
@@ -4701,8 +4685,7 @@ impl<'a> Parser<'a> {
4701
4685
if first && attrs_remaining_len > 0 u {
4702
4686
// We parsed attributes for the first item but didn't find it
4703
4687
let last_span = self . last_span ;
4704
- self . span_err ( last_span,
4705
- Parser :: expected_item_err ( attrs_remaining. as_slice ( ) ) ) ;
4688
+ self . span_err ( last_span, "expected item after attributes" ) ;
4706
4689
}
4707
4690
4708
4691
ast:: Mod {
@@ -4936,10 +4919,10 @@ impl<'a> Parser<'a> {
4936
4919
items : _,
4937
4920
foreign_items : foreign_items
4938
4921
} = self . parse_foreign_items ( first_item_attrs, true ) ;
4939
- if !attrs_remaining. is_empty ( ) {
4922
+ if ! attrs_remaining. is_empty ( ) {
4940
4923
let last_span = self . last_span ;
4941
4924
self . span_err ( last_span,
4942
- Parser :: expected_item_err ( attrs_remaining . as_slice ( ) ) ) ;
4925
+ "expected item after attributes" ) ;
4943
4926
}
4944
4927
assert ! ( self . token == token:: RBRACE ) ;
4945
4928
ast:: ForeignMod {
@@ -5069,7 +5052,7 @@ impl<'a> Parser<'a> {
5069
5052
fn parse_enum_def ( & mut self , _generics : & ast:: Generics ) -> EnumDef {
5070
5053
let mut variants = Vec :: new ( ) ;
5071
5054
let mut all_nullary = true ;
5072
- let mut have_disr = false ;
5055
+ let mut any_disr = None ;
5073
5056
while self . token != token:: RBRACE {
5074
5057
let variant_attrs = self . parse_outer_attributes ( ) ;
5075
5058
let vlo = self . span . lo ;
@@ -5101,8 +5084,8 @@ impl<'a> Parser<'a> {
5101
5084
}
5102
5085
kind = TupleVariantKind ( args) ;
5103
5086
} else if self . eat ( & token:: EQ ) {
5104
- have_disr = true ;
5105
5087
disr_expr = Some ( self . parse_expr ( ) ) ;
5088
+ any_disr = disr_expr. as_ref ( ) . map ( |expr| expr. span ) ;
5106
5089
kind = TupleVariantKind ( args) ;
5107
5090
} else {
5108
5091
kind = TupleVariantKind ( Vec :: new ( ) ) ;
@@ -5121,9 +5104,11 @@ impl<'a> Parser<'a> {
5121
5104
if !self . eat ( & token:: COMMA ) { break ; }
5122
5105
}
5123
5106
self . expect ( & token:: RBRACE ) ;
5124
- if have_disr && !all_nullary {
5125
- self . fatal ( "discriminator values can only be used with a c-like \
5126
- enum") ;
5107
+ match any_disr {
5108
+ Some ( disr_span) if !all_nullary =>
5109
+ self . span_err ( disr_span,
5110
+ "discriminator values can only be used with a c-like enum" ) ,
5111
+ _ => ( )
5127
5112
}
5128
5113
5129
5114
ast:: EnumDef { variants : variants }
0 commit comments