@@ -974,15 +974,22 @@ impl<'a> Parser<'a> {
974974 /// This version of parse param doesn't necessarily require identifier names.
975975 fn parse_param_general (
976976 & mut self ,
977+ is_self_allowed : bool ,
977978 is_trait_item : bool ,
978979 allow_c_variadic : bool ,
979980 is_name_required : impl Fn ( & token:: Token ) -> bool ,
980981 ) -> PResult < ' a , Param > {
981982 let lo = self . token . span ;
982983 let attrs = self . parse_outer_attributes ( ) ?;
984+
985+ // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
983986 if let Some ( mut param) = self . parse_self_param ( ) ? {
984987 param. attrs = attrs. into ( ) ;
985- return self . recover_bad_self_param ( param, is_trait_item) ;
988+ return if is_self_allowed {
989+ Ok ( param)
990+ } else {
991+ self . recover_bad_self_param ( param, is_trait_item)
992+ } ;
986993 }
987994
988995 let is_name_required = is_name_required ( & self . token ) ;
@@ -1207,6 +1214,7 @@ impl<'a> Parser<'a> {
12071214 }
12081215 } ;
12091216 match p. parse_param_general (
1217+ false ,
12101218 false ,
12111219 allow_c_variadic,
12121220 do_not_enforce_named_arguments_for_c_variadic
@@ -1359,60 +1367,25 @@ impl<'a> Parser<'a> {
13591367 Ok ( Some ( Param :: from_self ( ThinVec :: default ( ) , eself, eself_ident) ) )
13601368 }
13611369
1362- /// Returns the parsed optional self parameter with attributes and whether a self
1363- /// shortcut was used.
1364- fn parse_self_parameter_with_attrs ( & mut self ) -> PResult < ' a , Option < Param > > {
1365- let attrs = self . parse_outer_attributes ( ) ?;
1366- let param_opt = self . parse_self_param ( ) ?;
1367- Ok ( param_opt. map ( |mut param| {
1368- param. attrs = attrs. into ( ) ;
1369- param
1370- } ) )
1371- }
1372-
13731370 /// Parses the parameter list and result type of a function that may have a `self` parameter.
1374- fn parse_fn_decl_with_self < F > ( & mut self , parse_param_fn : F ) -> PResult < ' a , P < FnDecl > >
1375- where F : FnMut ( & mut Parser < ' a > ) -> PResult < ' a , Param > ,
1376- {
1377- self . expect ( & token:: OpenDelim ( token:: Paren ) ) ?;
1378-
1379- // Parse optional self argument.
1380- let self_param = self . parse_self_parameter_with_attrs ( ) ?;
1381-
1382- // Parse the rest of the function parameter list.
1383- let sep = SeqSep :: trailing_allowed ( token:: Comma ) ;
1384- let ( mut fn_inputs, recovered) = if let Some ( self_param) = self_param {
1385- if self . check ( & token:: CloseDelim ( token:: Paren ) ) {
1386- ( vec ! [ self_param] , false )
1387- } else if self . eat ( & token:: Comma ) {
1388- let mut fn_inputs = vec ! [ self_param] ;
1389- let ( mut input, _, recovered) = self . parse_seq_to_before_end (
1390- & token:: CloseDelim ( token:: Paren ) , sep, parse_param_fn) ?;
1391- fn_inputs. append ( & mut input) ;
1392- ( fn_inputs, recovered)
1393- } else {
1394- match self . expect_one_of ( & [ ] , & [ ] ) {
1395- Err ( err) => return Err ( err) ,
1396- Ok ( recovered) => ( vec ! [ self_param] , recovered) ,
1397- }
1398- }
1399- } else {
1400- let ( input, _, recovered) =
1401- self . parse_seq_to_before_end ( & token:: CloseDelim ( token:: Paren ) ,
1402- sep,
1403- parse_param_fn) ?;
1404- ( input, recovered)
1405- } ;
1371+ fn parse_fn_decl_with_self (
1372+ & mut self ,
1373+ is_name_required : impl Copy + Fn ( & token:: Token ) -> bool ,
1374+ ) -> PResult < ' a , P < FnDecl > > {
1375+ // Parse the arguments, starting out with `self` being allowed...
1376+ let mut is_self_allowed = true ;
1377+ let ( mut inputs, _) : ( Vec < _ > , _ ) = self . parse_paren_comma_seq ( |p| {
1378+ let res = p. parse_param_general ( is_self_allowed, true , false , is_name_required) ;
1379+ // ...but now that we've parsed the first argument, `self` is no longer allowed.
1380+ is_self_allowed = false ;
1381+ res
1382+ } ) ?;
14061383
1407- if !recovered {
1408- // Parse closing paren and return type.
1409- self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?;
1410- }
14111384 // Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
1412- self . deduplicate_recovered_params_names ( & mut fn_inputs ) ;
1385+ self . deduplicate_recovered_params_names ( & mut inputs ) ;
14131386
14141387 Ok ( P ( FnDecl {
1415- inputs : fn_inputs ,
1388+ inputs,
14161389 output : self . parse_ret_ty ( true ) ?,
14171390 c_variadic : false
14181391 } ) )
0 commit comments