@@ -3480,22 +3480,32 @@ 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
+
3483
3493
/// Parse a statement. may include decl.
3484
3494
/// Precondition: any attributes are parsed already
3485
3495
pub fn parse_stmt ( & mut self , item_attrs : Vec < Attribute > ) -> P < Stmt > {
3486
3496
maybe_whole ! ( self , NtStmt ) ;
3487
3497
3488
- fn check_expected_item ( p : & mut Parser , found_attrs : bool ) {
3498
+ fn check_expected_item ( p : & mut Parser , attrs : & [ Attribute ] ) {
3489
3499
// If we have attributes then we should have an item
3490
- if found_attrs {
3500
+ if !attrs . is_empty ( ) {
3491
3501
let last_span = p. last_span ;
3492
- p. span_err ( last_span, "expected item after attributes" ) ;
3502
+ p. span_err ( last_span, Parser :: expected_item_err ( attrs ) ) ;
3493
3503
}
3494
3504
}
3495
3505
3496
3506
let lo = self . span . lo ;
3497
3507
if self . is_keyword ( keywords:: Let ) {
3498
- check_expected_item ( self , ! item_attrs. is_empty ( ) ) ;
3508
+ check_expected_item ( self , item_attrs. as_slice ( ) ) ;
3499
3509
self . expect_keyword ( keywords:: Let ) ;
3500
3510
let decl = self . parse_let ( ) ;
3501
3511
P ( spanned ( lo, decl. span . hi , StmtDecl ( decl, ast:: DUMMY_NODE_ID ) ) )
@@ -3504,7 +3514,7 @@ impl<'a> Parser<'a> {
3504
3514
&& self . look_ahead ( 1 , |t| * t == token:: NOT ) {
3505
3515
// it's a macro invocation:
3506
3516
3507
- check_expected_item ( self , ! item_attrs. is_empty ( ) ) ;
3517
+ check_expected_item ( self , item_attrs. as_slice ( ) ) ;
3508
3518
3509
3519
// Potential trouble: if we allow macros with paths instead of
3510
3520
// idents, we'd need to look ahead past the whole path here...
@@ -3561,6 +3571,7 @@ impl<'a> Parser<'a> {
3561
3571
3562
3572
} else {
3563
3573
let found_attrs = !item_attrs. is_empty ( ) ;
3574
+ let item_err = Parser :: expected_item_err ( item_attrs. as_slice ( ) ) ;
3564
3575
match self . parse_item_or_view_item ( item_attrs, false ) {
3565
3576
IoviItem ( i) => {
3566
3577
let hi = i. span . hi ;
@@ -3575,7 +3586,10 @@ impl<'a> Parser<'a> {
3575
3586
self . fatal ( "foreign items are not allowed here" ) ;
3576
3587
}
3577
3588
IoviNone ( _) => {
3578
- check_expected_item ( self , found_attrs) ;
3589
+ if found_attrs {
3590
+ let last_span = self . last_span ;
3591
+ self . span_err ( last_span, item_err) ;
3592
+ }
3579
3593
3580
3594
// Remainder are line-expr stmts.
3581
3595
let e = self . parse_expr_res ( RestrictionStmtExpr ) ;
@@ -3653,7 +3667,8 @@ impl<'a> Parser<'a> {
3653
3667
token:: SEMI => {
3654
3668
if !attributes_box. is_empty ( ) {
3655
3669
let last_span = self . last_span ;
3656
- self . span_err ( last_span, "expected item after attributes" ) ;
3670
+ self . span_err ( last_span,
3671
+ Parser :: expected_item_err ( attributes_box. as_slice ( ) ) ) ;
3657
3672
attributes_box = Vec :: new ( ) ;
3658
3673
}
3659
3674
self . bump ( ) ; // empty
@@ -3739,7 +3754,8 @@ impl<'a> Parser<'a> {
3739
3754
3740
3755
if !attributes_box. is_empty ( ) {
3741
3756
let last_span = self . last_span ;
3742
- self . span_err ( last_span, "expected item after attributes" ) ;
3757
+ self . span_err ( last_span,
3758
+ Parser :: expected_item_err ( attributes_box. as_slice ( ) ) ) ;
3743
3759
}
3744
3760
3745
3761
let hi = self . span . hi ;
@@ -4685,7 +4701,8 @@ impl<'a> Parser<'a> {
4685
4701
if first && attrs_remaining_len > 0 u {
4686
4702
// We parsed attributes for the first item but didn't find it
4687
4703
let last_span = self . last_span ;
4688
- self . span_err ( last_span, "expected item after attributes" ) ;
4704
+ self . span_err ( last_span,
4705
+ Parser :: expected_item_err ( attrs_remaining. as_slice ( ) ) ) ;
4689
4706
}
4690
4707
4691
4708
ast:: Mod {
@@ -4919,10 +4936,10 @@ impl<'a> Parser<'a> {
4919
4936
items : _,
4920
4937
foreign_items : foreign_items
4921
4938
} = self . parse_foreign_items ( first_item_attrs, true ) ;
4922
- if ! attrs_remaining. is_empty ( ) {
4939
+ if !attrs_remaining. is_empty ( ) {
4923
4940
let last_span = self . last_span ;
4924
4941
self . span_err ( last_span,
4925
- "expected item after attributes" ) ;
4942
+ Parser :: expected_item_err ( attrs_remaining . as_slice ( ) ) ) ;
4926
4943
}
4927
4944
assert ! ( self . token == token:: RBRACE ) ;
4928
4945
ast:: ForeignMod {
0 commit comments