@@ -1744,7 +1744,16 @@ impl<'a> Parser<'a> {
1744
1744
fn parse_arg_general ( & mut self , require_name : bool ) -> PResult < ' a , Arg > {
1745
1745
maybe_whole ! ( self , NtArg , |x| x) ;
1746
1746
1747
- let parser_snapshot_before_pat = self . clone ( ) ;
1747
+ // If we see `ident :`, then we know that the argument is just of the
1748
+ // form `type`, which means we won't need to recover from parsing a
1749
+ // pattern and so we don't need to store a parser snapshot.
1750
+ let parser_snapshot_before_pat = if
1751
+ self . look_ahead ( 1 , |t| t. is_ident ( ) ) &&
1752
+ self . look_ahead ( 2 , |t| t == & token:: Colon ) {
1753
+ None
1754
+ } else {
1755
+ Some ( self . clone ( ) )
1756
+ } ;
1748
1757
1749
1758
// We're going to try parsing the argument as a pattern (even if it's not
1750
1759
// allowed, such as for trait methods without bodies). This way we can provide
@@ -1755,29 +1764,31 @@ impl<'a> Parser<'a> {
1755
1764
( pat, self . parse_ty ( ) ?)
1756
1765
} ;
1757
1766
1758
- let is_named_argument = self . is_named_argument ( ) ;
1759
1767
match pat_arg {
1760
1768
Ok ( ( pat, ty) ) => {
1761
1769
Ok ( Arg { ty, pat, id: ast:: DUMMY_NODE_ID } )
1762
1770
}
1763
1771
Err ( mut err) => {
1764
- if require_name || is_named_argument {
1765
- Err ( err)
1766
- } else {
1767
- err. cancel ( ) ;
1768
- // Recover from attempting to parse the argument as a pattern. This means
1769
- // the type is alone, with no name, e.g. `fn foo(u32)`.
1770
- mem:: replace ( self , parser_snapshot_before_pat) ;
1771
- debug ! ( "parse_arg_general ident_to_pat" ) ;
1772
- let ident = Ident :: new ( keywords:: Invalid . name ( ) , self . prev_span ) ;
1773
- let ty = self . parse_ty ( ) ?;
1774
- let pat = P ( Pat {
1775
- id : ast:: DUMMY_NODE_ID ,
1776
- node : PatKind :: Ident (
1777
- BindingMode :: ByValue ( Mutability :: Immutable ) , ident, None ) ,
1778
- span : ty. span ,
1779
- } ) ;
1780
- Ok ( Arg { ty, pat, id : ast:: DUMMY_NODE_ID } )
1772
+ match ( require_name || self . is_named_argument ( ) , parser_snapshot_before_pat) {
1773
+ ( true , _) | ( _, None ) => {
1774
+ Err ( err)
1775
+ }
1776
+ ( false , Some ( parser_snapshot_before_pat) ) => {
1777
+ err. cancel ( ) ;
1778
+ // Recover from attempting to parse the argument as a pattern. This means
1779
+ // the type is alone, with no name, e.g. `fn foo(u32)`.
1780
+ mem:: replace ( self , parser_snapshot_before_pat) ;
1781
+ debug ! ( "parse_arg_general ident_to_pat" ) ;
1782
+ let ident = Ident :: new ( keywords:: Invalid . name ( ) , self . prev_span ) ;
1783
+ let ty = self . parse_ty ( ) ?;
1784
+ let pat = P ( Pat {
1785
+ id : ast:: DUMMY_NODE_ID ,
1786
+ node : PatKind :: Ident (
1787
+ BindingMode :: ByValue ( Mutability :: Immutable ) , ident, None ) ,
1788
+ span : ty. span ,
1789
+ } ) ;
1790
+ Ok ( Arg { ty, pat, id : ast:: DUMMY_NODE_ID } )
1791
+ }
1781
1792
}
1782
1793
}
1783
1794
}
0 commit comments