@@ -14,9 +14,9 @@ use thin_vec::{ThinVec, thin_vec};
14
14
use super :: { Parser , PathStyle , SeqSep , TokenType , Trailing } ;
15
15
use crate :: errors:: {
16
16
self , DynAfterMut , ExpectedFnPathFoundFnKeyword , ExpectedMutOrConstInRawPointerType ,
17
- FnPointerCannotBeAsync , FnPointerCannotBeConst , FnPtrWithGenerics , FnPtrWithGenericsSugg ,
18
- HelpUseLatestEdition , InvalidDynKeyword , LifetimeAfterMut , NeedPlusAfterTraitObjectLifetime ,
19
- NestedCVariadicType , ReturnTypesUseThinArrow ,
17
+ FnPathFoundNamedParams , FnPointerCannotBeAsync , FnPointerCannotBeConst , FnPtrWithGenerics ,
18
+ FnPtrWithGenericsSugg , HelpUseLatestEdition , InvalidDynKeyword , LifetimeAfterMut ,
19
+ NeedPlusAfterTraitObjectLifetime , NestedCVariadicType , ReturnTypesUseThinArrow ,
20
20
} ;
21
21
use crate :: { exp, maybe_recover_from_interpolated_ty_qpath} ;
22
22
@@ -1203,6 +1203,8 @@ impl<'a> Parser<'a> {
1203
1203
1204
1204
err. emit ( ) ;
1205
1205
1206
+ path
1207
+ } else if let Some ( path) = self . recover_path_for_fn_or_fn_onece_or_fn_mut ( ) {
1206
1208
path
1207
1209
} else {
1208
1210
self . parse_path ( PathStyle :: Type ) ?
@@ -1268,6 +1270,59 @@ impl<'a> Parser<'a> {
1268
1270
}
1269
1271
}
1270
1272
1273
+ /// Recover Fn(usize) from Fn(x: usize)
1274
+ fn recover_path_for_fn_or_fn_onece_or_fn_mut ( & mut self ) -> Option < ast:: Path > {
1275
+ if !( self . token . is_ident_named ( sym:: FnOnce )
1276
+ || self . token . is_ident_named ( sym:: FnMut )
1277
+ || self . token . is_ident_named ( sym:: Fn ) )
1278
+ || !self . look_ahead ( 1 , |t| * t == TokenKind :: OpenParen )
1279
+ {
1280
+ return None ;
1281
+ }
1282
+
1283
+ let fn_token_span = self . token . span ;
1284
+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
1285
+ self . bump ( ) ;
1286
+ let args_lo = self . token . span ;
1287
+
1288
+ match self . parse_fn_decl ( |_| false , AllowPlus :: No , RecoverReturnSign :: No ) {
1289
+ Ok ( decl) => {
1290
+ for param in & decl. inputs {
1291
+ if !matches ! ( param. pat. kind, crate :: ast:: PatKind :: Missing ) {
1292
+ self . dcx ( )
1293
+ . emit_err ( FnPathFoundNamedParams { named_param_span : param. pat . span } ) ;
1294
+
1295
+ return Some ( ast:: Path {
1296
+ span : fn_token_span. to ( self . prev_token . span ) ,
1297
+ segments : thin_vec ! [ ast:: PathSegment {
1298
+ ident: Ident :: new( sym:: Fn , fn_token_span) ,
1299
+ id: DUMMY_NODE_ID ,
1300
+ args: Some ( P ( ast:: GenericArgs :: Parenthesized (
1301
+ ast:: ParenthesizedArgs {
1302
+ span: args_lo. to( self . prev_token. span) ,
1303
+ inputs: decl
1304
+ . inputs
1305
+ . iter( )
1306
+ . map( |param| { param. ty. clone( ) } )
1307
+ . collect( ) ,
1308
+ inputs_span: args_lo. until( decl. output. span( ) ) ,
1309
+ output: decl. output. clone( ) ,
1310
+ }
1311
+ ) ) ) ,
1312
+ } ] ,
1313
+ tokens : None ,
1314
+ } ) ;
1315
+ }
1316
+ }
1317
+ }
1318
+ Err ( diag) => {
1319
+ diag. cancel ( ) ;
1320
+ }
1321
+ }
1322
+ self . restore_snapshot ( snapshot) ;
1323
+ None
1324
+ }
1325
+
1271
1326
/// Optionally parses `for<$generic_params>`.
1272
1327
pub ( super ) fn parse_late_bound_lifetime_defs (
1273
1328
& mut self ,
0 commit comments