@@ -117,7 +117,8 @@ impl<'a> Parser<'a> {
117117
118118impl < ' a > Parser < ' a > {
119119 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 } ;
121122 self . parse_item_ ( fn_parse_mode, force_collect) . map ( |i| i. map ( P ) )
122123 }
123124
@@ -952,16 +953,20 @@ impl<'a> Parser<'a> {
952953 & mut self ,
953954 force_collect : ForceCollect ,
954955 ) -> 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 } ;
956958 self . parse_assoc_item ( fn_parse_mode, force_collect)
957959 }
958960
959961 pub fn parse_trait_item (
960962 & mut self ,
961963 force_collect : ForceCollect ,
962964 ) -> 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+ } ;
965970 self . parse_assoc_item ( fn_parse_mode, force_collect)
966971 }
967972
@@ -1238,7 +1243,8 @@ impl<'a> Parser<'a> {
12381243 & mut self ,
12391244 force_collect : ForceCollect ,
12401245 ) -> 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 } ;
12421248 Ok ( self . parse_item_ ( fn_parse_mode, force_collect) ?. map (
12431249 |Item { attrs, id, span, vis, kind, tokens } | {
12441250 let kind = match ForeignItemKind :: try_from ( kind) {
@@ -2110,7 +2116,8 @@ impl<'a> Parser<'a> {
21102116 let inherited_vis =
21112117 Visibility { span : DUMMY_SP , kind : VisibilityKind :: Inherited , tokens : None } ;
21122118 // 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 } ;
21142121 match self . parse_fn (
21152122 & mut AttrVec :: new ( ) ,
21162123 fn_parse_mode,
@@ -2378,6 +2385,9 @@ pub(crate) struct FnParseMode {
23782385 /// * The span is from Edition 2015. In particular, you can get a
23792386 /// 2015 span inside a 2021 crate using macros.
23802387 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 ,
23812391 /// If this flag is set to `true`, then plain, semicolon-terminated function
23822392 /// prototypes are not allowed here.
23832393 ///
@@ -2399,6 +2409,18 @@ pub(crate) struct FnParseMode {
23992409 pub ( super ) req_body : bool ,
24002410}
24012411
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+
24022424/// Parsing of functions and methods.
24032425impl < ' a > Parser < ' a > {
24042426 /// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`.
@@ -2414,11 +2436,8 @@ impl<'a> Parser<'a> {
24142436 let header = self . parse_fn_front_matter ( vis, case, FrontMatterParsingMode :: Function ) ?; // `const ... fn`
24152437 let ident = self . parse_ident ( ) ?; // `foo`
24162438 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+ {
24222441 Ok ( decl) => decl,
24232442 Err ( old_err) => {
24242443 // If we see `for Ty ...` then user probably meant `impl` item.
@@ -2936,18 +2955,21 @@ impl<'a> Parser<'a> {
29362955 /// Parses the parameter list and result type of a function declaration.
29372956 pub ( super ) fn parse_fn_decl (
29382957 & mut self ,
2939- req_name : ReqName ,
2958+ fn_parse_mode : & FnParseMode ,
29402959 ret_allow_plus : AllowPlus ,
29412960 recover_return_sign : RecoverReturnSign ,
29422961 ) -> PResult < ' a , P < FnDecl > > {
29432962 Ok ( P ( FnDecl {
2944- inputs : self . parse_fn_params ( req_name ) ?,
2963+ inputs : self . parse_fn_params ( fn_parse_mode ) ?,
29452964 output : self . parse_ret_ty ( ret_allow_plus, RecoverQPath :: Yes , recover_return_sign) ?,
29462965 } ) )
29472966 }
29482967
29492968 /// 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 > > {
29512973 let mut first_param = true ;
29522974 // Parse the arguments, starting out with `self` being allowed...
29532975 if self . token != TokenKind :: OpenParen
@@ -2963,7 +2985,7 @@ impl<'a> Parser<'a> {
29632985 let ( mut params, _) = self . parse_paren_comma_seq ( |p| {
29642986 p. recover_vcs_conflict_marker ( ) ;
29652987 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| {
29672989 let guar = e. emit ( ) ;
29682990 // When parsing a param failed, we should check to make the span of the param
29692991 // not contain '(' before it.
@@ -2994,7 +3016,7 @@ impl<'a> Parser<'a> {
29943016 /// - `recover_arg_parse` is used to recover from a failed argument parse.
29953017 pub ( super ) fn parse_param_general (
29963018 & mut self ,
2997- req_name : ReqName ,
3019+ fn_parse_mode : & FnParseMode ,
29983020 first_param : bool ,
29993021 recover_arg_parse : bool ,
30003022 ) -> PResult < ' a , Param > {
@@ -3010,16 +3032,22 @@ impl<'a> Parser<'a> {
30103032
30113033 let is_name_required = match this. token . kind {
30123034 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+ ) ,
30143038 } ;
30153039 let ( pat, ty) = if is_name_required || this. is_named_param ( ) {
30163040 debug ! ( "parse_param_general parse_pat (is_name_required:{})" , is_name_required) ;
30173041 let ( pat, colon) = this. parse_fn_param_pat_colon ( ) ?;
30183042 if !colon {
30193043 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+ ) {
30233051 let guar = err. emit ( ) ;
30243052 Ok ( ( dummy_arg ( ident, guar) , Trailing :: No , UsePreAttrPos :: No ) )
30253053 } else {
0 commit comments