@@ -482,36 +482,37 @@ impl<'a> Parser<'a> {
482
482
( lo. to ( span) , self . mk_unary ( UnOp :: Deref , e) )
483
483
}
484
484
token:: BinOp ( token:: And ) | token:: AndAnd => self . parse_borrow_expr ( lo) ?,
485
- token:: Ident ( ..) if self . token . is_keyword ( kw:: Box ) => {
486
- self . bump ( ) ;
487
- let e = self . parse_prefix_expr ( None ) ;
488
- let ( span, e) = self . interpolated_or_expr_span ( e) ?;
489
- let span = lo. to ( span) ;
490
- self . sess . gated_spans . gate ( sym:: box_syntax, span) ;
491
- ( span, ExprKind :: Box ( e) )
492
- }
493
- token:: Ident ( ..) if self . token . is_ident_named ( sym:: not) => {
494
- // `not` is just an ordinary identifier in Rust-the-language,
495
- // but as `rustc`-the-compiler, we can issue clever diagnostics
496
- // for confused users who really want to say `!`
497
- let token_cannot_continue_expr = |t : & Token | match t. kind {
498
- // These tokens can start an expression after `!`, but
499
- // can't continue an expression after an ident
500
- token:: Ident ( name, is_raw) => token:: ident_can_begin_expr ( name, t. span , is_raw) ,
501
- token:: Literal ( ..) | token:: Pound => true ,
502
- _ => t. is_whole_expr ( ) ,
503
- } ;
504
- if !self . look_ahead ( 1 , token_cannot_continue_expr) {
505
- return self . parse_dot_or_call_expr ( Some ( attrs) ) ;
506
- }
507
-
485
+ token:: Ident ( ..) if self . token . is_keyword ( kw:: Box ) => self . parse_box_expr ( lo) ?,
486
+ token:: Ident ( ..) if self . is_mistaken_not_ident_negation ( ) => {
508
487
self . recover_not_expr ( lo) ?
509
488
}
510
489
_ => return self . parse_dot_or_call_expr ( Some ( attrs) ) ,
511
490
} ;
512
491
return Ok ( self . mk_expr ( lo. to ( hi) , ex, attrs) ) ;
513
492
}
514
493
494
+ /// Parse `box expr`.
495
+ fn parse_box_expr ( & mut self , lo : Span ) -> PResult < ' a , ( Span , ExprKind ) > {
496
+ self . bump ( ) ;
497
+ let e = self . parse_prefix_expr ( None ) ;
498
+ let ( span, e) = self . interpolated_or_expr_span ( e) ?;
499
+ let span = lo. to ( span) ;
500
+ self . sess . gated_spans . gate ( sym:: box_syntax, span) ;
501
+ Ok ( ( span, ExprKind :: Box ( e) ) )
502
+ }
503
+
504
+ fn is_mistaken_not_ident_negation ( & self ) -> bool {
505
+ let token_cannot_continue_expr = |t : & Token | match t. kind {
506
+ // These tokens can start an expression after `!`, but
507
+ // can't continue an expression after an ident
508
+ token:: Ident ( name, is_raw) => token:: ident_can_begin_expr ( name, t. span , is_raw) ,
509
+ token:: Literal ( ..) | token:: Pound => true ,
510
+ _ => t. is_whole_expr ( ) ,
511
+ } ;
512
+ self . token . is_ident_named ( sym:: not) && self . look_ahead ( 1 , token_cannot_continue_expr)
513
+ }
514
+
515
+ /// Recover on `not expr` in favor of `!expr`.
515
516
fn recover_not_expr ( & mut self , lo : Span ) -> PResult < ' a , ( Span , ExprKind ) > {
516
517
self . bump ( ) ;
517
518
// Emit the error ...
0 commit comments