@@ -482,36 +482,37 @@ impl<'a> Parser<'a> {
482482 ( lo. to ( span) , self . mk_unary ( UnOp :: Deref , e) )
483483 }
484484 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 ( ) => {
508487 self . recover_not_expr ( lo) ?
509488 }
510489 _ => return self . parse_dot_or_call_expr ( Some ( attrs) ) ,
511490 } ;
512491 return Ok ( self . mk_expr ( lo. to ( hi) , ex, attrs) ) ;
513492 }
514493
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`.
515516 fn recover_not_expr ( & mut self , lo : Span ) -> PResult < ' a , ( Span , ExprKind ) > {
516517 self . bump ( ) ;
517518 // Emit the error ...
0 commit comments