@@ -2932,6 +2932,8 @@ impl<'a> Parser<'a> {
29322932 /// Parses the parameter list of a function, including the `(` and `)` delimiters.
29332933 pub ( super ) fn parse_fn_params ( & mut self , req_name : ReqName ) -> PResult < ' a , ThinVec < Param > > {
29342934 let mut first_param = true ;
2935+ let is_bare_fn_ptr = self . prev_token . is_keyword ( kw:: Fn ) ;
2936+
29352937 // Parse the arguments, starting out with `self` being allowed...
29362938 if self . token != TokenKind :: OpenParen
29372939 // might be typo'd trait impl, handled elsewhere
@@ -2946,22 +2948,23 @@ impl<'a> Parser<'a> {
29462948 let ( mut params, _) = self . parse_paren_comma_seq ( |p| {
29472949 p. recover_vcs_conflict_marker ( ) ;
29482950 let snapshot = p. create_snapshot_for_diagnostic ( ) ;
2949- let param = p. parse_param_general ( req_name, first_param, true ) . or_else ( |e| {
2950- let guar = e. emit ( ) ;
2951- // When parsing a param failed, we should check to make the span of the param
2952- // not contain '(' before it.
2953- // For example when parsing `*mut Self` in function `fn oof(*mut Self)`.
2954- let lo = if let TokenKind :: OpenParen = p. prev_token . kind {
2955- p. prev_token . span . shrink_to_hi ( )
2956- } else {
2957- p. prev_token . span
2958- } ;
2959- p. restore_snapshot ( snapshot) ;
2960- // Skip every token until next possible arg or end.
2961- p. eat_to_tokens ( & [ exp ! ( Comma ) , exp ! ( CloseParen ) ] ) ;
2962- // Create a placeholder argument for proper arg count (issue #34264).
2963- Ok ( dummy_arg ( Ident :: new ( sym:: dummy, lo. to ( p. prev_token . span ) ) , guar) )
2964- } ) ;
2951+ let param =
2952+ p. parse_param_general ( req_name, first_param, true , is_bare_fn_ptr) . or_else ( |e| {
2953+ let guar = e. emit ( ) ;
2954+ // When parsing a param failed, we should check to make the span of the param
2955+ // not contain '(' before it.
2956+ // For example when parsing `*mut Self` in function `fn oof(*mut Self)`.
2957+ let lo = if let TokenKind :: OpenParen = p. prev_token . kind {
2958+ p. prev_token . span . shrink_to_hi ( )
2959+ } else {
2960+ p. prev_token . span
2961+ } ;
2962+ p. restore_snapshot ( snapshot) ;
2963+ // Skip every token until next possible arg or end.
2964+ p. eat_to_tokens ( & [ exp ! ( Comma ) , exp ! ( CloseParen ) ] ) ;
2965+ // Create a placeholder argument for proper arg count (issue #34264).
2966+ Ok ( dummy_arg ( Ident :: new ( sym:: dummy, lo. to ( p. prev_token . span ) ) , guar) )
2967+ } ) ;
29652968 // ...now that we've parsed the first argument, `self` is no longer allowed.
29662969 first_param = false ;
29672970 param
@@ -2975,11 +2978,13 @@ impl<'a> Parser<'a> {
29752978 ///
29762979 /// - `self` is syntactically allowed when `first_param` holds.
29772980 /// - `recover_arg_parse` is used to recover from a failed argument parse.
2981+ /// - `is_bare_fn_ptr` is used to improve diagnostics for bare fn ptrs.
29782982 pub ( super ) fn parse_param_general (
29792983 & mut self ,
29802984 req_name : ReqName ,
29812985 first_param : bool ,
29822986 recover_arg_parse : bool ,
2987+ is_bare_fn_ptr : bool ,
29832988 ) -> PResult < ' a , Param > {
29842989 let lo = self . token . span ;
29852990 let attrs = self . parse_outer_attributes ( ) ?;
@@ -3040,6 +3045,7 @@ impl<'a> Parser<'a> {
30403045 ty = this. unexpected_any ( ) ;
30413046 }
30423047 }
3048+
30433049 match ty {
30443050 Ok ( ty) => {
30453051 let pat = this. mk_pat ( ty. span , PatKind :: Missing ) ;
@@ -3052,7 +3058,7 @@ impl<'a> Parser<'a> {
30523058 // Recover from attempting to parse the argument as a type without pattern.
30533059 err. cancel ( ) ;
30543060 this. restore_snapshot ( parser_snapshot_before_ty) ;
3055- this. recover_arg_parse ( ) ?
3061+ this. recover_arg_parse ( !is_bare_fn_ptr ) ?
30563062 }
30573063 Err ( err) => return Err ( err) ,
30583064 }
0 commit comments