@@ -4,6 +4,7 @@ use super::{BlockMode, Parser, PathStyle, Restrictions, TokenType};
4
4
use super :: { SemiColonMode , SeqSep , TokenExpectType } ;
5
5
use crate :: maybe_recover_from_interpolated_ty_qpath;
6
6
7
+ use log:: debug;
7
8
use rustc_ast:: ast:: { self , AttrStyle , AttrVec , CaptureBy , Field , Lit , UnOp , DUMMY_NODE_ID } ;
8
9
use rustc_ast:: ast:: { AnonConst , BinOp , BinOpKind , FnDecl , FnRetTy , MacCall , Param , Ty , TyKind } ;
9
10
use rustc_ast:: ast:: { Arm , Async , BlockCheckMode , Expr , ExprKind , Label , Movability , RangeLimits } ;
@@ -431,19 +432,23 @@ impl<'a> Parser<'a> {
431
432
/// Parses a prefix-unary-operator expr.
432
433
fn parse_prefix_expr ( & mut self , attrs : Option < AttrVec > ) -> PResult < ' a , P < Expr > > {
433
434
let attrs = self . parse_or_use_outer_attributes ( attrs) ?;
434
- let lo = self . token . span ;
435
- // Note: when adding new unary operators, don't forget to adjust TokenKind::can_begin_expr()
436
- let ( hi, ex) = match self . token . uninterpolate ( ) . kind {
437
- token:: Not => self . parse_unary_expr ( lo, UnOp :: Not ) , // `!expr`
438
- token:: Tilde => self . recover_tilde_expr ( lo) , // `~expr`
439
- token:: BinOp ( token:: Minus ) => self . parse_unary_expr ( lo, UnOp :: Neg ) , // `-expr`
440
- token:: BinOp ( token:: Star ) => self . parse_unary_expr ( lo, UnOp :: Deref ) , // `*expr`
441
- token:: BinOp ( token:: And ) | token:: AndAnd => self . parse_borrow_expr ( lo) ,
442
- token:: Ident ( ..) if self . token . is_keyword ( kw:: Box ) => self . parse_box_expr ( lo) ,
443
- token:: Ident ( ..) if self . is_mistaken_not_ident_negation ( ) => self . recover_not_expr ( lo) ,
444
- _ => return self . parse_dot_or_call_expr ( Some ( attrs) ) ,
445
- } ?;
446
- Ok ( self . mk_expr ( lo. to ( hi) , ex, attrs) )
435
+ self . maybe_collect_tokens ( !attrs. is_empty ( ) , |this| {
436
+ let lo = this. token . span ;
437
+ // Note: when adding new unary operators, don't forget to adjust TokenKind::can_begin_expr()
438
+ let ( hi, ex) = match this. token . uninterpolate ( ) . kind {
439
+ token:: Not => this. parse_unary_expr ( lo, UnOp :: Not ) , // `!expr`
440
+ token:: Tilde => this. recover_tilde_expr ( lo) , // `~expr`
441
+ token:: BinOp ( token:: Minus ) => this. parse_unary_expr ( lo, UnOp :: Neg ) , // `-expr`
442
+ token:: BinOp ( token:: Star ) => this. parse_unary_expr ( lo, UnOp :: Deref ) , // `*expr`
443
+ token:: BinOp ( token:: And ) | token:: AndAnd => this. parse_borrow_expr ( lo) ,
444
+ token:: Ident ( ..) if this. token . is_keyword ( kw:: Box ) => this. parse_box_expr ( lo) ,
445
+ token:: Ident ( ..) if this. is_mistaken_not_ident_negation ( ) => {
446
+ this. recover_not_expr ( lo)
447
+ }
448
+ _ => return this. parse_dot_or_call_expr ( Some ( attrs) ) ,
449
+ } ?;
450
+ Ok ( this. mk_expr ( lo. to ( hi) , ex, attrs) )
451
+ } )
447
452
}
448
453
449
454
fn parse_prefix_expr_common ( & mut self , lo : Span ) -> PResult < ' a , ( Span , P < Expr > ) > {
@@ -998,6 +1003,21 @@ impl<'a> Parser<'a> {
998
1003
}
999
1004
}
1000
1005
1006
+ fn maybe_collect_tokens (
1007
+ & mut self ,
1008
+ has_outer_attrs : bool ,
1009
+ f : impl FnOnce ( & mut Self ) -> PResult < ' a , P < Expr > > ,
1010
+ ) -> PResult < ' a , P < Expr > > {
1011
+ if has_outer_attrs {
1012
+ let ( mut expr, tokens) = self . collect_tokens ( f) ?;
1013
+ debug ! ( "maybe_collect_tokens: Collected tokens for {:?} (tokens {:?}" , expr, tokens) ;
1014
+ expr. tokens = Some ( tokens) ;
1015
+ Ok ( expr)
1016
+ } else {
1017
+ f ( self )
1018
+ }
1019
+ }
1020
+
1001
1021
fn parse_lit_expr ( & mut self , attrs : AttrVec ) -> PResult < ' a , P < Expr > > {
1002
1022
let lo = self . token . span ;
1003
1023
match self . parse_opt_lit ( ) {
@@ -2169,7 +2189,7 @@ impl<'a> Parser<'a> {
2169
2189
}
2170
2190
2171
2191
crate fn mk_expr ( & self , span : Span , kind : ExprKind , attrs : AttrVec ) -> P < Expr > {
2172
- P ( Expr { kind, span, attrs, id : DUMMY_NODE_ID } )
2192
+ P ( Expr { kind, span, attrs, id : DUMMY_NODE_ID , tokens : None } )
2173
2193
}
2174
2194
2175
2195
pub ( super ) fn mk_expr_err ( & self , span : Span ) -> P < Expr > {
0 commit comments