@@ -1780,27 +1780,32 @@ impl<'a> Parser<'a> {
1780
1780
( pat, self . parse_ty ( ) ?)
1781
1781
} else {
1782
1782
debug ! ( "parse_arg_general ident_to_pat" ) ;
1783
+ let parser_snapshot_before_ty = self . clone ( ) ;
1784
+ let mut ty = self . parse_ty ( ) ;
1785
+ if ty. is_ok ( ) && self . token == token:: Colon {
1786
+ // This wasn't actually a type, but a pattern looking like a type,
1787
+ // so we are going to rollback and re-parse for recovery.
1788
+ ty = self . unexpected ( ) ;
1789
+ }
1790
+ match ty {
1791
+ Ok ( ty) => {
1792
+ let ident = Ident :: new ( keywords:: Invalid . name ( ) , self . prev_span ) ;
1793
+ let pat = P ( Pat {
1794
+ id : ast:: DUMMY_NODE_ID ,
1795
+ node : PatKind :: Ident (
1796
+ BindingMode :: ByValue ( Mutability :: Immutable ) , ident, None ) ,
1797
+ span : ty. span ,
1798
+ } ) ;
1799
+ ( pat, ty)
1800
+ }
1801
+ Err ( mut err) => {
1802
+ // Recover from attempting to parse the argument as a type without pattern.
1803
+ err. cancel ( ) ;
1804
+ mem:: replace ( self , parser_snapshot_before_ty) ;
1805
+ let pat = self . parse_pat ( ) ?;
1806
+ self . expect ( & token:: Colon ) ?;
1807
+ let ty = self . parse_ty ( ) ?;
1783
1808
1784
- let parser_snapshot_before_pat = self . clone ( ) ;
1785
-
1786
- // Once we can use edition 2018 in the compiler,
1787
- // replace this with real try blocks.
1788
- macro_rules! try_block {
1789
- ( $( $inside: tt) * ) => (
1790
- ( ||{ :: std:: ops:: Try :: from_ok( { $( $inside) * } ) } ) ( )
1791
- )
1792
- }
1793
-
1794
- // We're going to try parsing the argument as a pattern (even though it's not
1795
- // allowed). This way we can provide better errors to the user.
1796
- let pat_arg: PResult < ' a , _ > = try_block ! {
1797
- let pat = self . parse_pat( ) ?;
1798
- self . expect( & token:: Colon ) ?;
1799
- ( pat, self . parse_ty( ) ?)
1800
- } ;
1801
-
1802
- match pat_arg {
1803
- Ok ( ( pat, ty) ) => {
1804
1809
let mut err = self . diagnostic ( ) . struct_span_err_with_code (
1805
1810
pat. span ,
1806
1811
"patterns aren't allowed in methods without bodies" ,
@@ -1813,6 +1818,7 @@ impl<'a> Parser<'a> {
1813
1818
Applicability :: MachineApplicable ,
1814
1819
) ;
1815
1820
err. emit ( ) ;
1821
+
1816
1822
// Pretend the pattern is `_`, to avoid duplicate errors from AST validation.
1817
1823
let pat = P ( Pat {
1818
1824
node : PatKind :: Wild ,
@@ -1821,22 +1827,6 @@ impl<'a> Parser<'a> {
1821
1827
} ) ;
1822
1828
( pat, ty)
1823
1829
}
1824
- Err ( mut err) => {
1825
- err. cancel ( ) ;
1826
- // Recover from attempting to parse the argument as a pattern. This means
1827
- // the type is alone, with no name, e.g. `fn foo(u32)`.
1828
- mem:: replace ( self , parser_snapshot_before_pat) ;
1829
- debug ! ( "parse_arg_general ident_to_pat" ) ;
1830
- let ident = Ident :: new ( keywords:: Invalid . name ( ) , self . prev_span ) ;
1831
- let ty = self . parse_ty ( ) ?;
1832
- let pat = P ( Pat {
1833
- id : ast:: DUMMY_NODE_ID ,
1834
- node : PatKind :: Ident (
1835
- BindingMode :: ByValue ( Mutability :: Immutable ) , ident, None ) ,
1836
- span : ty. span ,
1837
- } ) ;
1838
- ( pat, ty)
1839
- }
1840
1830
}
1841
1831
} ;
1842
1832
0 commit comments