@@ -3625,29 +3625,16 @@ impl<'a> Parser<'a> {
3625
3625
pat = PatKind :: Box ( subpat) ;
3626
3626
} else if self . token . is_path_start ( ) {
3627
3627
// 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) ?;
3651
3638
} else {
3652
3639
let ( qself, path) = if self . eat_lt ( ) {
3653
3640
// Parse a qualified path
@@ -3659,6 +3646,17 @@ impl<'a> Parser<'a> {
3659
3646
( None , self . parse_path ( PathStyle :: Expr ) ?)
3660
3647
} ;
3661
3648
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
+ }
3662
3660
token:: DotDotDot => {
3663
3661
// Parse range
3664
3662
let hi = self . last_span . hi ;
@@ -3895,16 +3893,33 @@ impl<'a> Parser<'a> {
3895
3893
node : StmtKind :: Local ( self . parse_local ( attrs. into ( ) ) ?) ,
3896
3894
span : mk_sp ( lo, self . last_span . hi ) ,
3897
3895
}
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 ) ?;
3902
3901
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
+ }
3907
3921
3922
+ // it's a macro invocation
3908
3923
let id = match self . token {
3909
3924
token:: OpenDelim ( _) => keywords:: Invalid . ident ( ) , // no special identifier
3910
3925
_ => self . parse_ident ( ) ?,
0 commit comments