@@ -2932,6 +2932,8 @@ impl<'a> Parser<'a> {
2932
2932
/// Parses the parameter list of a function, including the `(` and `)` delimiters.
2933
2933
pub ( super ) fn parse_fn_params ( & mut self , req_name : ReqName ) -> PResult < ' a , ThinVec < Param > > {
2934
2934
let mut first_param = true ;
2935
+ let is_bare_fn_ptr = self . prev_token . is_keyword ( kw:: Fn ) ;
2936
+
2935
2937
// Parse the arguments, starting out with `self` being allowed...
2936
2938
if self . token != TokenKind :: OpenParen
2937
2939
// might be typo'd trait impl, handled elsewhere
@@ -2946,22 +2948,23 @@ impl<'a> Parser<'a> {
2946
2948
let ( mut params, _) = self . parse_paren_comma_seq ( |p| {
2947
2949
p. recover_vcs_conflict_marker ( ) ;
2948
2950
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
+ } ) ;
2965
2968
// ...now that we've parsed the first argument, `self` is no longer allowed.
2966
2969
first_param = false ;
2967
2970
param
@@ -2975,11 +2978,13 @@ impl<'a> Parser<'a> {
2975
2978
///
2976
2979
/// - `self` is syntactically allowed when `first_param` holds.
2977
2980
/// - `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.
2978
2982
pub ( super ) fn parse_param_general (
2979
2983
& mut self ,
2980
2984
req_name : ReqName ,
2981
2985
first_param : bool ,
2982
2986
recover_arg_parse : bool ,
2987
+ is_bare_fn_ptr : bool ,
2983
2988
) -> PResult < ' a , Param > {
2984
2989
let lo = self . token . span ;
2985
2990
let attrs = self . parse_outer_attributes ( ) ?;
@@ -3040,6 +3045,7 @@ impl<'a> Parser<'a> {
3040
3045
ty = this. unexpected_any ( ) ;
3041
3046
}
3042
3047
}
3048
+
3043
3049
match ty {
3044
3050
Ok ( ty) => {
3045
3051
let pat = this. mk_pat ( ty. span , PatKind :: Missing ) ;
@@ -3052,7 +3058,7 @@ impl<'a> Parser<'a> {
3052
3058
// Recover from attempting to parse the argument as a type without pattern.
3053
3059
err. cancel ( ) ;
3054
3060
this. restore_snapshot ( parser_snapshot_before_ty) ;
3055
- this. recover_arg_parse ( ) ?
3061
+ this. recover_arg_parse ( !is_bare_fn_ptr ) ?
3056
3062
}
3057
3063
Err ( err) => return Err ( err) ,
3058
3064
}
0 commit comments