@@ -3625,29 +3625,16 @@ impl<'a> Parser<'a> {
36253625 pat = PatKind :: Box ( subpat) ;
36263626 } else if self . token . is_path_start ( ) {
36273627 // Parse pattern starting with a path
3628- if self . token . is_ident ( ) && self . look_ahead ( 1 , |t| * t != token:: DotDotDot &&
3629- * t != token:: OpenDelim ( token:: Brace ) &&
3630- * t != token:: OpenDelim ( token:: Paren ) &&
3631- * t != token:: ModSep ) {
3632- // Plain idents have some extra abilities here compared to general paths
3633- if self . look_ahead ( 1 , |t| * t == token:: Not ) {
3634- // Parse macro invocation
3635- let path = self . parse_ident_into_path ( ) ?;
3636- self . bump ( ) ;
3637- let delim = self . expect_open_delim ( ) ?;
3638- let tts = self . parse_seq_to_end (
3639- & token:: CloseDelim ( delim) ,
3640- SeqSep :: none ( ) , |p| p. parse_token_tree ( ) ) ?;
3641- let mac = Mac_ { path : path, tts : tts } ;
3642- pat = PatKind :: Mac ( codemap:: Spanned { node : mac,
3643- span : mk_sp ( lo, self . last_span . hi ) } ) ;
3644- } else {
3645- // Parse ident @ pat
3646- // This can give false positives and parse nullary enums,
3647- // they are dealt with later in resolve
3648- let binding_mode = BindingMode :: ByValue ( Mutability :: Immutable ) ;
3649- pat = self . parse_pat_ident ( binding_mode) ?;
3650- }
3628+ if self . token . is_ident ( ) && self . look_ahead ( 1 , |t| match * t {
3629+ token:: OpenDelim ( token:: Paren ) | token:: OpenDelim ( token:: Brace ) |
3630+ token:: DotDotDot | token:: ModSep | token:: Not => false ,
3631+ _ => true ,
3632+ } ) {
3633+ // Parse ident @ pat
3634+ // This can give false positives and parse nullary enums,
3635+ // they are dealt with later in resolve
3636+ let binding_mode = BindingMode :: ByValue ( Mutability :: Immutable ) ;
3637+ pat = self . parse_pat_ident ( binding_mode) ?;
36513638 } else {
36523639 let ( qself, path) = if self . eat_lt ( ) {
36533640 // Parse a qualified path
@@ -3659,6 +3646,17 @@ impl<'a> Parser<'a> {
36593646 ( None , self . parse_path ( PathStyle :: Expr ) ?)
36603647 } ;
36613648 match self . token {
3649+ token:: Not if qself. is_none ( ) => {
3650+ // Parse macro invocation
3651+ self . bump ( ) ;
3652+ let delim = self . expect_open_delim ( ) ?;
3653+ let tts = self . parse_seq_to_end (
3654+ & token:: CloseDelim ( delim) ,
3655+ SeqSep :: none ( ) , |p| p. parse_token_tree ( ) ) ?;
3656+ let mac = Mac_ { path : path, tts : tts } ;
3657+ pat = PatKind :: Mac ( codemap:: Spanned { node : mac,
3658+ span : mk_sp ( lo, self . last_span . hi ) } ) ;
3659+ }
36623660 token:: DotDotDot => {
36633661 // Parse range
36643662 let hi = self . last_span . hi ;
@@ -3895,16 +3893,33 @@ impl<'a> Parser<'a> {
38953893 node : StmtKind :: Local ( self . parse_local ( attrs. into ( ) ) ?) ,
38963894 span : mk_sp ( lo, self . last_span . hi ) ,
38973895 }
3898- } else if self . token . is_ident ( )
3899- && !self . token . is_any_keyword ( )
3900- && self . look_ahead ( 1 , |t| * t == token:: Not ) {
3901- // it's a macro invocation:
3896+ } else if self . token . is_path_start ( ) && self . token != token:: Lt && {
3897+ !self . check_keyword ( keywords:: Union ) ||
3898+ self . look_ahead ( 1 , |t| * t == token:: Not || * t == token:: ModSep )
3899+ } {
3900+ let pth = self . parse_path ( PathStyle :: Expr ) ?;
39023901
3903- // Potential trouble: if we allow macros with paths instead of
3904- // idents, we'd need to look ahead past the whole path here...
3905- let pth = self . parse_ident_into_path ( ) ?;
3906- self . bump ( ) ;
3902+ if !self . eat ( & token:: Not ) {
3903+ let expr = if self . check ( & token:: OpenDelim ( token:: Brace ) ) {
3904+ self . parse_struct_expr ( lo, pth, ThinVec :: new ( ) ) ?
3905+ } else {
3906+ let hi = self . last_span . hi ;
3907+ self . mk_expr ( lo, hi, ExprKind :: Path ( None , pth) , ThinVec :: new ( ) )
3908+ } ;
3909+
3910+ let expr = self . with_res ( Restrictions :: RESTRICTION_STMT_EXPR , |this| {
3911+ let expr = this. parse_dot_or_call_expr_with ( expr, lo, attrs. into ( ) ) ?;
3912+ this. parse_assoc_expr_with ( 0 , LhsExpr :: AlreadyParsed ( expr) )
3913+ } ) ?;
3914+
3915+ return Ok ( Some ( Stmt {
3916+ id : ast:: DUMMY_NODE_ID ,
3917+ node : StmtKind :: Expr ( expr) ,
3918+ span : mk_sp ( lo, self . last_span . hi ) ,
3919+ } ) ) ;
3920+ }
39073921
3922+ // it's a macro invocation
39083923 let id = match self . token {
39093924 token:: OpenDelim ( _) => keywords:: Invalid . ident ( ) , // no special identifier
39103925 _ => self . parse_ident ( ) ?,
0 commit comments