@@ -3480,22 +3480,32 @@ impl<'a> Parser<'a> {
34803480 } )
34813481 }
34823482
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+
34833493 /// Parse a statement. may include decl.
34843494 /// Precondition: any attributes are parsed already
34853495 pub fn parse_stmt ( & mut self , item_attrs : Vec < Attribute > ) -> P < Stmt > {
34863496 maybe_whole ! ( self , NtStmt ) ;
34873497
3488- fn check_expected_item ( p : & mut Parser , found_attrs : bool ) {
3498+ fn check_expected_item ( p : & mut Parser , attrs : & [ Attribute ] ) {
34893499 // If we have attributes then we should have an item
3490- if found_attrs {
3500+ if !attrs . is_empty ( ) {
34913501 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 ) ) ;
34933503 }
34943504 }
34953505
34963506 let lo = self . span . lo ;
34973507 if self . is_keyword ( keywords:: Let ) {
3498- check_expected_item ( self , ! item_attrs. is_empty ( ) ) ;
3508+ check_expected_item ( self , item_attrs. as_slice ( ) ) ;
34993509 self . expect_keyword ( keywords:: Let ) ;
35003510 let decl = self . parse_let ( ) ;
35013511 P ( spanned ( lo, decl. span . hi , StmtDecl ( decl, ast:: DUMMY_NODE_ID ) ) )
@@ -3504,7 +3514,7 @@ impl<'a> Parser<'a> {
35043514 && self . look_ahead ( 1 , |t| * t == token:: NOT ) {
35053515 // it's a macro invocation:
35063516
3507- check_expected_item ( self , ! item_attrs. is_empty ( ) ) ;
3517+ check_expected_item ( self , item_attrs. as_slice ( ) ) ;
35083518
35093519 // Potential trouble: if we allow macros with paths instead of
35103520 // idents, we'd need to look ahead past the whole path here...
@@ -3561,6 +3571,7 @@ impl<'a> Parser<'a> {
35613571
35623572 } else {
35633573 let found_attrs = !item_attrs. is_empty ( ) ;
3574+ let item_err = Parser :: expected_item_err ( item_attrs. as_slice ( ) ) ;
35643575 match self . parse_item_or_view_item ( item_attrs, false ) {
35653576 IoviItem ( i) => {
35663577 let hi = i. span . hi ;
@@ -3575,7 +3586,10 @@ impl<'a> Parser<'a> {
35753586 self . fatal ( "foreign items are not allowed here" ) ;
35763587 }
35773588 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+ }
35793593
35803594 // Remainder are line-expr stmts.
35813595 let e = self . parse_expr_res ( RestrictionStmtExpr ) ;
@@ -3653,7 +3667,8 @@ impl<'a> Parser<'a> {
36533667 token:: SEMI => {
36543668 if !attributes_box. is_empty ( ) {
36553669 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 ( ) ) ) ;
36573672 attributes_box = Vec :: new ( ) ;
36583673 }
36593674 self . bump ( ) ; // empty
@@ -3739,7 +3754,8 @@ impl<'a> Parser<'a> {
37393754
37403755 if !attributes_box. is_empty ( ) {
37413756 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 ( ) ) ) ;
37433759 }
37443760
37453761 let hi = self . span . hi ;
@@ -4685,7 +4701,8 @@ impl<'a> Parser<'a> {
46854701 if first && attrs_remaining_len > 0 u {
46864702 // We parsed attributes for the first item but didn't find it
46874703 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 ( ) ) ) ;
46894706 }
46904707
46914708 ast:: Mod {
@@ -4919,10 +4936,10 @@ impl<'a> Parser<'a> {
49194936 items : _,
49204937 foreign_items : foreign_items
49214938 } = self . parse_foreign_items ( first_item_attrs, true ) ;
4922- if ! attrs_remaining. is_empty ( ) {
4939+ if !attrs_remaining. is_empty ( ) {
49234940 let last_span = self . last_span ;
49244941 self . span_err ( last_span,
4925- "expected item after attributes" ) ;
4942+ Parser :: expected_item_err ( attrs_remaining . as_slice ( ) ) ) ;
49264943 }
49274944 assert ! ( self . token == token:: RBRACE ) ;
49284945 ast:: ForeignMod {
0 commit comments