@@ -117,7 +117,8 @@ impl<'a> Parser<'a> {
117
117
118
118
impl < ' a > Parser < ' a > {
119
119
pub fn parse_item ( & mut self , force_collect : ForceCollect ) -> PResult < ' a , Option < P < Item > > > {
120
- let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
120
+ let fn_parse_mode =
121
+ FnParseMode { req_name : |_| true , context : FnContext :: Free , req_body : true } ;
121
122
self . parse_item_ ( fn_parse_mode, force_collect) . map ( |i| i. map ( P ) )
122
123
}
123
124
@@ -952,16 +953,20 @@ impl<'a> Parser<'a> {
952
953
& mut self ,
953
954
force_collect : ForceCollect ,
954
955
) -> PResult < ' a , Option < Option < P < AssocItem > > > > {
955
- let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
956
+ let fn_parse_mode =
957
+ FnParseMode { req_name : |_| true , context : FnContext :: Impl , req_body : true } ;
956
958
self . parse_assoc_item ( fn_parse_mode, force_collect)
957
959
}
958
960
959
961
pub fn parse_trait_item (
960
962
& mut self ,
961
963
force_collect : ForceCollect ,
962
964
) -> PResult < ' a , Option < Option < P < AssocItem > > > > {
963
- let fn_parse_mode =
964
- FnParseMode { req_name : |edition| edition >= Edition :: Edition2018 , req_body : false } ;
965
+ let fn_parse_mode = FnParseMode {
966
+ req_name : |edition| edition >= Edition :: Edition2018 ,
967
+ context : FnContext :: Trait ,
968
+ req_body : false ,
969
+ } ;
965
970
self . parse_assoc_item ( fn_parse_mode, force_collect)
966
971
}
967
972
@@ -1238,7 +1243,8 @@ impl<'a> Parser<'a> {
1238
1243
& mut self ,
1239
1244
force_collect : ForceCollect ,
1240
1245
) -> PResult < ' a , Option < Option < P < ForeignItem > > > > {
1241
- let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : false } ;
1246
+ let fn_parse_mode =
1247
+ FnParseMode { req_name : |_| true , context : FnContext :: Free , req_body : false } ;
1242
1248
Ok ( self . parse_item_ ( fn_parse_mode, force_collect) ?. map (
1243
1249
|Item { attrs, id, span, vis, kind, tokens } | {
1244
1250
let kind = match ForeignItemKind :: try_from ( kind) {
@@ -2110,7 +2116,8 @@ impl<'a> Parser<'a> {
2110
2116
let inherited_vis =
2111
2117
Visibility { span : DUMMY_SP , kind : VisibilityKind :: Inherited , tokens : None } ;
2112
2118
// We use `parse_fn` to get a span for the function
2113
- let fn_parse_mode = FnParseMode { req_name : |_| true , req_body : true } ;
2119
+ let fn_parse_mode =
2120
+ FnParseMode { req_name : |_| true , context : FnContext :: Free , req_body : true } ;
2114
2121
match self . parse_fn (
2115
2122
& mut AttrVec :: new ( ) ,
2116
2123
fn_parse_mode,
@@ -2378,6 +2385,9 @@ pub(crate) struct FnParseMode {
2378
2385
/// * The span is from Edition 2015. In particular, you can get a
2379
2386
/// 2015 span inside a 2021 crate using macros.
2380
2387
pub ( super ) req_name : ReqName ,
2388
+ /// The context in which this function is parsed, used for diagnostics.
2389
+ /// This indicates the fn is a free function or method and so on.
2390
+ pub ( super ) context : FnContext ,
2381
2391
/// If this flag is set to `true`, then plain, semicolon-terminated function
2382
2392
/// prototypes are not allowed here.
2383
2393
///
@@ -2399,6 +2409,18 @@ pub(crate) struct FnParseMode {
2399
2409
pub ( super ) req_body : bool ,
2400
2410
}
2401
2411
2412
+ /// The context in which a function is parsed.
2413
+ /// FIXME(estebank, xizheyin): Use more variants.
2414
+ #[ derive( Clone , Copy , PartialEq , Eq ) ]
2415
+ pub ( crate ) enum FnContext {
2416
+ /// Free context.
2417
+ Free ,
2418
+ /// A Trait context.
2419
+ Trait ,
2420
+ /// An Impl block.
2421
+ Impl ,
2422
+ }
2423
+
2402
2424
/// Parsing of functions and methods.
2403
2425
impl < ' a > Parser < ' a > {
2404
2426
/// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`.
@@ -2414,11 +2436,8 @@ impl<'a> Parser<'a> {
2414
2436
let header = self . parse_fn_front_matter ( vis, case, FrontMatterParsingMode :: Function ) ?; // `const ... fn`
2415
2437
let ident = self . parse_ident ( ) ?; // `foo`
2416
2438
let mut generics = self . parse_generics ( ) ?; // `<'a, T, ...>`
2417
- let decl = match self . parse_fn_decl (
2418
- fn_parse_mode. req_name ,
2419
- AllowPlus :: Yes ,
2420
- RecoverReturnSign :: Yes ,
2421
- ) {
2439
+ let decl = match self . parse_fn_decl ( & fn_parse_mode, AllowPlus :: Yes , RecoverReturnSign :: Yes )
2440
+ {
2422
2441
Ok ( decl) => decl,
2423
2442
Err ( old_err) => {
2424
2443
// If we see `for Ty ...` then user probably meant `impl` item.
@@ -2936,18 +2955,21 @@ impl<'a> Parser<'a> {
2936
2955
/// Parses the parameter list and result type of a function declaration.
2937
2956
pub ( super ) fn parse_fn_decl (
2938
2957
& mut self ,
2939
- req_name : ReqName ,
2958
+ fn_parse_mode : & FnParseMode ,
2940
2959
ret_allow_plus : AllowPlus ,
2941
2960
recover_return_sign : RecoverReturnSign ,
2942
2961
) -> PResult < ' a , P < FnDecl > > {
2943
2962
Ok ( P ( FnDecl {
2944
- inputs : self . parse_fn_params ( req_name ) ?,
2963
+ inputs : self . parse_fn_params ( fn_parse_mode ) ?,
2945
2964
output : self . parse_ret_ty ( ret_allow_plus, RecoverQPath :: Yes , recover_return_sign) ?,
2946
2965
} ) )
2947
2966
}
2948
2967
2949
2968
/// Parses the parameter list of a function, including the `(` and `)` delimiters.
2950
- pub ( super ) fn parse_fn_params ( & mut self , req_name : ReqName ) -> PResult < ' a , ThinVec < Param > > {
2969
+ pub ( super ) fn parse_fn_params (
2970
+ & mut self ,
2971
+ fn_parse_mode : & FnParseMode ,
2972
+ ) -> PResult < ' a , ThinVec < Param > > {
2951
2973
let mut first_param = true ;
2952
2974
// Parse the arguments, starting out with `self` being allowed...
2953
2975
if self . token != TokenKind :: OpenParen
@@ -2963,7 +2985,7 @@ impl<'a> Parser<'a> {
2963
2985
let ( mut params, _) = self . parse_paren_comma_seq ( |p| {
2964
2986
p. recover_vcs_conflict_marker ( ) ;
2965
2987
let snapshot = p. create_snapshot_for_diagnostic ( ) ;
2966
- let param = p. parse_param_general ( req_name , first_param, true ) . or_else ( |e| {
2988
+ let param = p. parse_param_general ( fn_parse_mode , first_param, true ) . or_else ( |e| {
2967
2989
let guar = e. emit ( ) ;
2968
2990
// When parsing a param failed, we should check to make the span of the param
2969
2991
// not contain '(' before it.
@@ -2994,7 +3016,7 @@ impl<'a> Parser<'a> {
2994
3016
/// - `recover_arg_parse` is used to recover from a failed argument parse.
2995
3017
pub ( super ) fn parse_param_general (
2996
3018
& mut self ,
2997
- req_name : ReqName ,
3019
+ fn_parse_mode : & FnParseMode ,
2998
3020
first_param : bool ,
2999
3021
recover_arg_parse : bool ,
3000
3022
) -> PResult < ' a , Param > {
@@ -3010,16 +3032,22 @@ impl<'a> Parser<'a> {
3010
3032
3011
3033
let is_name_required = match this. token . kind {
3012
3034
token:: DotDotDot => false ,
3013
- _ => req_name ( this. token . span . with_neighbor ( this. prev_token . span ) . edition ( ) ) ,
3035
+ _ => ( fn_parse_mode. req_name ) (
3036
+ this. token . span . with_neighbor ( this. prev_token . span ) . edition ( ) ,
3037
+ ) ,
3014
3038
} ;
3015
3039
let ( pat, ty) = if is_name_required || this. is_named_param ( ) {
3016
3040
debug ! ( "parse_param_general parse_pat (is_name_required:{})" , is_name_required) ;
3017
3041
let ( pat, colon) = this. parse_fn_param_pat_colon ( ) ?;
3018
3042
if !colon {
3019
3043
let mut err = this. unexpected ( ) . unwrap_err ( ) ;
3020
- return if let Some ( ident) =
3021
- this. parameter_without_type ( & mut err, pat, is_name_required, first_param)
3022
- {
3044
+ return if let Some ( ident) = this. parameter_without_type (
3045
+ & mut err,
3046
+ pat,
3047
+ is_name_required,
3048
+ first_param,
3049
+ fn_parse_mode,
3050
+ ) {
3023
3051
let guar = err. emit ( ) ;
3024
3052
Ok ( ( dummy_arg ( ident, guar) , Trailing :: No , UsePreAttrPos :: No ) )
3025
3053
} else {
0 commit comments