@@ -116,7 +116,8 @@ impl<'a> Parser<'a> {
116116
117117impl < ' a > Parser < ' a > {
118118 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 } ;
120121 self . parse_item_ ( fn_parse_mode, force_collect) . map ( |i| i. map ( Box :: new) )
121122 }
122123
@@ -975,16 +976,20 @@ impl<'a> Parser<'a> {
975976 & mut self ,
976977 force_collect : ForceCollect ,
977978 ) -> 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 } ;
979981 self . parse_assoc_item ( fn_parse_mode, force_collect)
980982 }
981983
982984 pub fn parse_trait_item (
983985 & mut self ,
984986 force_collect : ForceCollect ,
985987 ) -> 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+ } ;
988993 self . parse_assoc_item ( fn_parse_mode, force_collect)
989994 }
990995
@@ -1261,7 +1266,8 @@ impl<'a> Parser<'a> {
12611266 & mut self ,
12621267 force_collect : ForceCollect ,
12631268 ) -> 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 } ;
12651271 Ok ( self . parse_item_ ( fn_parse_mode, force_collect) ?. map (
12661272 |Item { attrs, id, span, vis, kind, tokens } | {
12671273 let kind = match ForeignItemKind :: try_from ( kind) {
@@ -2135,7 +2141,8 @@ impl<'a> Parser<'a> {
21352141 let inherited_vis =
21362142 Visibility { span : DUMMY_SP , kind : VisibilityKind :: Inherited , tokens : None } ;
21372143 // 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 } ;
21392146 match self . parse_fn (
21402147 & mut AttrVec :: new ( ) ,
21412148 fn_parse_mode,
@@ -2403,6 +2410,9 @@ pub(crate) struct FnParseMode {
24032410 /// * The span is from Edition 2015. In particular, you can get a
24042411 /// 2015 span inside a 2021 crate using macros.
24052412 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 ,
24062416 /// If this flag is set to `true`, then plain, semicolon-terminated function
24072417 /// prototypes are not allowed here.
24082418 ///
@@ -2424,6 +2434,18 @@ pub(crate) struct FnParseMode {
24242434 pub ( super ) req_body : bool ,
24252435}
24262436
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+
24272449/// Parsing of functions and methods.
24282450impl < ' a > Parser < ' a > {
24292451 /// Parse a function starting from the front matter (`const ...`) to the body `{ ... }` or `;`.
@@ -2439,11 +2461,8 @@ impl<'a> Parser<'a> {
24392461 let header = self . parse_fn_front_matter ( vis, case, FrontMatterParsingMode :: Function ) ?; // `const ... fn`
24402462 let ident = self . parse_ident ( ) ?; // `foo`
24412463 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+ {
24472466 Ok ( decl) => decl,
24482467 Err ( old_err) => {
24492468 // If we see `for Ty ...` then user probably meant `impl` item.
@@ -2961,18 +2980,21 @@ impl<'a> Parser<'a> {
29612980 /// Parses the parameter list and result type of a function declaration.
29622981 pub ( super ) fn parse_fn_decl (
29632982 & mut self ,
2964- req_name : ReqName ,
2983+ fn_parse_mode : & FnParseMode ,
29652984 ret_allow_plus : AllowPlus ,
29662985 recover_return_sign : RecoverReturnSign ,
29672986 ) -> PResult < ' a , Box < FnDecl > > {
29682987 Ok ( Box :: new ( FnDecl {
2969- inputs : self . parse_fn_params ( req_name ) ?,
2988+ inputs : self . parse_fn_params ( fn_parse_mode ) ?,
29702989 output : self . parse_ret_ty ( ret_allow_plus, RecoverQPath :: Yes , recover_return_sign) ?,
29712990 } ) )
29722991 }
29732992
29742993 /// 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 > > {
29762998 let mut first_param = true ;
29772999 // Parse the arguments, starting out with `self` being allowed...
29783000 if self . token != TokenKind :: OpenParen
@@ -2988,7 +3010,7 @@ impl<'a> Parser<'a> {
29883010 let ( mut params, _) = self . parse_paren_comma_seq ( |p| {
29893011 p. recover_vcs_conflict_marker ( ) ;
29903012 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| {
29923014 let guar = e. emit ( ) ;
29933015 // When parsing a param failed, we should check to make the span of the param
29943016 // not contain '(' before it.
@@ -3019,7 +3041,7 @@ impl<'a> Parser<'a> {
30193041 /// - `recover_arg_parse` is used to recover from a failed argument parse.
30203042 pub ( super ) fn parse_param_general (
30213043 & mut self ,
3022- req_name : ReqName ,
3044+ fn_parse_mode : & FnParseMode ,
30233045 first_param : bool ,
30243046 recover_arg_parse : bool ,
30253047 ) -> PResult < ' a , Param > {
@@ -3035,16 +3057,22 @@ impl<'a> Parser<'a> {
30353057
30363058 let is_name_required = match this. token . kind {
30373059 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+ ) ,
30393063 } ;
30403064 let ( pat, ty) = if is_name_required || this. is_named_param ( ) {
30413065 debug ! ( "parse_param_general parse_pat (is_name_required:{})" , is_name_required) ;
30423066 let ( pat, colon) = this. parse_fn_param_pat_colon ( ) ?;
30433067 if !colon {
30443068 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+ ) {
30483076 let guar = err. emit ( ) ;
30493077 Ok ( ( dummy_arg ( ident, guar) , Trailing :: No , UsePreAttrPos :: No ) )
30503078 } else {
0 commit comments