@@ -116,7 +116,8 @@ impl<'a> Parser<'a> {
116
116
117
117
impl < ' a > Parser < ' a > {
118
118
pub fn parse_item ( & mut self , force_collect : ForceCollect ) -> PResult < ' a , Option < Box < Item > > > {
119
- let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
119
+ let fn_parse_mode =
120
+ FnParseMode { req_name : |_| true , context : FnContext :: Free , req_body : true } ;
120
121
self . parse_item_ ( fn_parse_mode, force_collect) . map ( |i| i. map ( Box :: new) )
121
122
}
122
123
@@ -975,16 +976,20 @@ impl<'a> Parser<'a> {
975
976
& mut self ,
976
977
force_collect : ForceCollect ,
977
978
) -> PResult < ' a , Option < Option < Box < AssocItem > > > > {
978
- let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
979
+ let fn_parse_mode =
980
+ FnParseMode { req_name : |_| true , context : FnContext :: Impl , req_body : true } ;
979
981
self . parse_assoc_item ( fn_parse_mode, force_collect)
980
982
}
981
983
982
984
pub fn parse_trait_item (
983
985
& mut self ,
984
986
force_collect : ForceCollect ,
985
987
) -> PResult < ' a , Option < Option < Box < AssocItem > > > > {
986
- let fn_parse_mode =
987
- FnParseMode { req_name : |edition| edition >= Edition :: Edition2018 , req_body : false } ;
988
+ let fn_parse_mode = FnParseMode {
989
+ req_name : |edition| edition >= Edition :: Edition2018 ,
990
+ context : FnContext :: Trait ,
991
+ req_body : false ,
992
+ } ;
988
993
self . parse_assoc_item ( fn_parse_mode, force_collect)
989
994
}
990
995
@@ -1261,7 +1266,8 @@ impl<'a> Parser<'a> {
1261
1266
& mut self ,
1262
1267
force_collect : ForceCollect ,
1263
1268
) -> PResult < ' a , Option < Option < Box < ForeignItem > > > > {
1264
- let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : false } ;
1269
+ let fn_parse_mode =
1270
+ FnParseMode { req_name : |_| true , context : FnContext :: Free , req_body : false } ;
1265
1271
Ok ( self . parse_item_ ( fn_parse_mode, force_collect) ?. map (
1266
1272
|Item { attrs, id, span, vis, kind, tokens } | {
1267
1273
let kind = match ForeignItemKind :: try_from ( kind) {
@@ -2135,7 +2141,8 @@ impl<'a> Parser<'a> {
2135
2141
let inherited_vis =
2136
2142
Visibility { span : DUMMY_SP , kind : VisibilityKind :: Inherited , tokens : None } ;
2137
2143
// We use `parse_fn` to get a span for the function
2138
- let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
2144
+ let fn_parse_mode =
2145
+ FnParseMode { req_name : |_| true , context : FnContext :: Free , req_body : true } ;
2139
2146
match self . parse_fn (
2140
2147
& mut AttrVec :: new ( ) ,
2141
2148
fn_parse_mode,
@@ -2403,6 +2410,9 @@ pub(crate) struct FnParseMode {
2403
2410
/// * The span is from Edition 2015. In particular, you can get a
2404
2411
/// 2015 span inside a 2021 crate using macros.
2405
2412
pub ( super ) req_name : ReqName ,
2413
+ /// The context in which this function is parsed, used for diagnostics.
2414
+ /// This indicates the fn is a free function or method and so on.
2415
+ pub ( super ) context : FnContext ,
2406
2416
/// If this flag is set to `true`, then plain, semicolon-terminated function
2407
2417
/// prototypes are not allowed here.
2408
2418
///
@@ -2424,6 +2434,18 @@ pub(crate) struct FnParseMode {
2424
2434
pub ( super ) req_body : bool ,
2425
2435
}
2426
2436
2437
+ /// The context in which a function is parsed.
2438
+ /// FIXME(estebank, xizheyin): Use more variants.
2439
+ #[ derive( Clone , Copy , PartialEq , Eq ) ]
2440
+ pub ( crate ) enum FnContext {
2441
+ /// Free context.
2442
+ Free ,
2443
+ /// A Trait context.
2444
+ Trait ,
2445
+ /// An Impl block.
2446
+ Impl ,
2447
+ }
2448
+
2427
2449
/// Parsing of functions and methods.
2428
2450
impl < ' a > Parser < ' a > {
2429
2451
/// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`.
@@ -2439,11 +2461,8 @@ impl<'a> Parser<'a> {
2439
2461
let header = self . parse_fn_front_matter ( vis, case, FrontMatterParsingMode :: Function ) ?; // `const ... fn`
2440
2462
let ident = self . parse_ident ( ) ?; // `foo`
2441
2463
let mut generics = self . parse_generics ( ) ?; // `<'a, T, ...>`
2442
- let decl = match self . parse_fn_decl (
2443
- fn_parse_mode. req_name ,
2444
- AllowPlus :: Yes ,
2445
- RecoverReturnSign :: Yes ,
2446
- ) {
2464
+ let decl = match self . parse_fn_decl ( & fn_parse_mode, AllowPlus :: Yes , RecoverReturnSign :: Yes )
2465
+ {
2447
2466
Ok ( decl) => decl,
2448
2467
Err ( old_err) => {
2449
2468
// If we see `for Ty ...` then user probably meant `impl` item.
@@ -2961,18 +2980,21 @@ impl<'a> Parser<'a> {
2961
2980
/// Parses the parameter list and result type of a function declaration.
2962
2981
pub ( super ) fn parse_fn_decl (
2963
2982
& mut self ,
2964
- req_name : ReqName ,
2983
+ fn_parse_mode : & FnParseMode ,
2965
2984
ret_allow_plus : AllowPlus ,
2966
2985
recover_return_sign : RecoverReturnSign ,
2967
2986
) -> PResult < ' a , Box < FnDecl > > {
2968
2987
Ok ( Box :: new ( FnDecl {
2969
- inputs : self . parse_fn_params ( req_name ) ?,
2988
+ inputs : self . parse_fn_params ( fn_parse_mode ) ?,
2970
2989
output : self . parse_ret_ty ( ret_allow_plus, RecoverQPath :: Yes , recover_return_sign) ?,
2971
2990
} ) )
2972
2991
}
2973
2992
2974
2993
/// Parses the parameter list of a function, including the `(` and `)` delimiters.
2975
- pub ( super ) fn parse_fn_params ( & mut self , req_name : ReqName ) -> PResult < ' a , ThinVec < Param > > {
2994
+ pub ( super ) fn parse_fn_params (
2995
+ & mut self ,
2996
+ fn_parse_mode : & FnParseMode ,
2997
+ ) -> PResult < ' a , ThinVec < Param > > {
2976
2998
let mut first_param = true ;
2977
2999
// Parse the arguments, starting out with `self` being allowed...
2978
3000
if self . token != TokenKind :: OpenParen
@@ -2988,7 +3010,7 @@ impl<'a> Parser<'a> {
2988
3010
let ( mut params, _) = self . parse_paren_comma_seq ( |p| {
2989
3011
p. recover_vcs_conflict_marker ( ) ;
2990
3012
let snapshot = p. create_snapshot_for_diagnostic ( ) ;
2991
- let param = p. parse_param_general ( req_name , first_param, true ) . or_else ( |e| {
3013
+ let param = p. parse_param_general ( fn_parse_mode , first_param, true ) . or_else ( |e| {
2992
3014
let guar = e. emit ( ) ;
2993
3015
// When parsing a param failed, we should check to make the span of the param
2994
3016
// not contain '(' before it.
@@ -3019,7 +3041,7 @@ impl<'a> Parser<'a> {
3019
3041
/// - `recover_arg_parse` is used to recover from a failed argument parse.
3020
3042
pub ( super ) fn parse_param_general (
3021
3043
& mut self ,
3022
- req_name : ReqName ,
3044
+ fn_parse_mode : & FnParseMode ,
3023
3045
first_param : bool ,
3024
3046
recover_arg_parse : bool ,
3025
3047
) -> PResult < ' a , Param > {
@@ -3035,16 +3057,22 @@ impl<'a> Parser<'a> {
3035
3057
3036
3058
let is_name_required = match this. token . kind {
3037
3059
token:: DotDotDot => false ,
3038
- _ => req_name ( this. token . span . with_neighbor ( this. prev_token . span ) . edition ( ) ) ,
3060
+ _ => ( fn_parse_mode. req_name ) (
3061
+ this. token . span . with_neighbor ( this. prev_token . span ) . edition ( ) ,
3062
+ ) ,
3039
3063
} ;
3040
3064
let ( pat, ty) = if is_name_required || this. is_named_param ( ) {
3041
3065
debug ! ( "parse_param_general parse_pat (is_name_required:{})" , is_name_required) ;
3042
3066
let ( pat, colon) = this. parse_fn_param_pat_colon ( ) ?;
3043
3067
if !colon {
3044
3068
let mut err = this. unexpected ( ) . unwrap_err ( ) ;
3045
- return if let Some ( ident) =
3046
- this. parameter_without_type ( & mut err, pat, is_name_required, first_param)
3047
- {
3069
+ return if let Some ( ident) = this. parameter_without_type (
3070
+ & mut err,
3071
+ pat,
3072
+ is_name_required,
3073
+ first_param,
3074
+ fn_parse_mode,
3075
+ ) {
3048
3076
let guar = err. emit ( ) ;
3049
3077
Ok ( ( dummy_arg ( ident, guar) , Trailing :: No , UsePreAttrPos :: No ) )
3050
3078
} else {
0 commit comments