@@ -1744,7 +1744,16 @@ impl<'a> Parser<'a> {
17441744 fn parse_arg_general ( & mut self , require_name : bool ) -> PResult < ' a , Arg > {
17451745 maybe_whole ! ( self , NtArg , |x| x) ;
17461746
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+ } ;
17481757
17491758 // We're going to try parsing the argument as a pattern (even if it's not
17501759 // allowed, such as for trait methods without bodies). This way we can provide
@@ -1755,29 +1764,31 @@ impl<'a> Parser<'a> {
17551764 ( pat, self . parse_ty ( ) ?)
17561765 } ;
17571766
1758- let is_named_argument = self . is_named_argument ( ) ;
17591767 match pat_arg {
17601768 Ok ( ( pat, ty) ) => {
17611769 Ok ( Arg { ty, pat, id: ast:: DUMMY_NODE_ID } )
17621770 }
17631771 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+ }
17811792 }
17821793 }
17831794 }
0 commit comments