From 41d37a452c022168d79b7e59a837f04a45dc2902 Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Fri, 8 Aug 2025 15:48:17 +0530 Subject: [PATCH 1/4] refactor(parse): separate self parameter parsing from general parameter parsing --- compiler/rustc_parse/src/parser/item.rs | 30 ++++++++++++------------- compiler/rustc_parse/src/parser/path.rs | 2 +- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index cb7c56494332c..3053719d18c84 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2948,8 +2948,6 @@ impl<'a> Parser<'a> { /// Parses the parameter list of a function, including the `(` and `)` delimiters. pub(super) fn parse_fn_params(&mut self, req_name: ReqName) -> PResult<'a, ThinVec> { - let mut first_param = true; - // Parse the arguments, starting out with `self` being allowed... if self.token != TokenKind::OpenParen // might be typo'd trait impl, handled elsewhere && !self.token.is_keyword(kw::For) @@ -2959,11 +2957,20 @@ impl<'a> Parser<'a> { .emit_err(errors::MissingFnParams { span: self.prev_token.span.shrink_to_hi() }); return Ok(ThinVec::new()); } + + let mut params = ThinVec::new(); - let (mut params, _) = self.parse_paren_comma_seq(|p| { + //Parse the self parameter as first parameter + if let Some(mut self_param) = self.parse_self_param()?{ + let self_attrs = self.parse_outer_attributes()?; + self_param.attrs = self.attrs; + params.push(self_param); + } + + let (mut remaining_params, _) = self.parse_paren_comma_seq(|p| { p.recover_vcs_conflict_marker(); let snapshot = p.create_snapshot_for_diagnostic(); - let param = p.parse_param_general(req_name, first_param, true).or_else(|e| { + let param = p.parse_param_general(req_name, true).or_else(|e| { let guar = e.emit(); // When parsing a param failed, we should check to make the span of the param // not contain '(' before it. @@ -2979,10 +2986,10 @@ impl<'a> Parser<'a> { // Create a placeholder argument for proper arg count (issue #34264). Ok(dummy_arg(Ident::new(sym::dummy, lo.to(p.prev_token.span)), guar)) }); - // ...now that we've parsed the first argument, `self` is no longer allowed. - first_param = false; param })?; + // Combine self parameter (if any) with remaining parameters + params.extend(remaining_params); // Replace duplicated recovered params with `_` pattern to avoid unnecessary errors. self.deduplicate_recovered_params_names(&mut params); Ok(params) @@ -2990,24 +2997,15 @@ impl<'a> Parser<'a> { /// Parses a single function parameter. /// - /// - `self` is syntactically allowed when `first_param` holds. /// - `recover_arg_parse` is used to recover from a failed argument parse. pub(super) fn parse_param_general( &mut self, req_name: ReqName, - first_param: bool, recover_arg_parse: bool, ) -> PResult<'a, Param> { let lo = self.token.span; let attrs = self.parse_outer_attributes()?; self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| { - // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here. - if let Some(mut param) = this.parse_self_param()? { - param.attrs = attrs; - let res = if first_param { Ok(param) } else { this.recover_bad_self_param(param) }; - return Ok((res?, Trailing::No, UsePreAttrPos::No)); - } - let is_name_required = match this.token.kind { token::DotDotDot => false, _ => req_name(this.token.span.with_neighbor(this.prev_token.span).edition()), @@ -3018,7 +3016,7 @@ impl<'a> Parser<'a> { if !colon { let mut err = this.unexpected().unwrap_err(); return if let Some(ident) = - this.parameter_without_type(&mut err, pat, is_name_required, first_param) + this.parameter_without_type(&mut err, pat, is_name_required, false) { let guar = err.emit(); Ok((dummy_arg(ident, guar), Trailing::No, UsePreAttrPos::No)) diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 8e65ab99c5e65..2f21f766bf785 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -400,7 +400,7 @@ impl<'a> Parser<'a> { let dcx = self.dcx(); let parse_params_result = self.parse_paren_comma_seq(|p| { - let param = p.parse_param_general(|_| false, false, false); + let param = p.parse_param_general(|_| false, false); param.map(move |param| { if !matches!(param.pat.kind, PatKind::Missing) { dcx.emit_err(FnPathFoundNamedParams { From cbfd0462d1984e5ed4ed283e19d4596636f2dc0e Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Tue, 19 Aug 2025 08:37:29 +0530 Subject: [PATCH 2/4] Update compiler/rustc_parse/src/parser/item.rs Co-authored-by: Nicholas Nethercote --- compiler/rustc_parse/src/parser/item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 3053719d18c84..1b6aed465da65 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2960,7 +2960,7 @@ impl<'a> Parser<'a> { let mut params = ThinVec::new(); - //Parse the self parameter as first parameter + // Parse the self parameter as first parameter if let Some(mut self_param) = self.parse_self_param()?{ let self_attrs = self.parse_outer_attributes()?; self_param.attrs = self.attrs; From 34d18f1db699e82638ff0ce95b9f200b71452f22 Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Tue, 19 Aug 2025 08:38:18 +0530 Subject: [PATCH 3/4] Update compiler/rustc_parse/src/parser/item.rs Co-authored-by: Nicholas Nethercote --- compiler/rustc_parse/src/parser/item.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 1b6aed465da65..cc37640df26d5 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2961,7 +2961,7 @@ impl<'a> Parser<'a> { let mut params = ThinVec::new(); // Parse the self parameter as first parameter - if let Some(mut self_param) = self.parse_self_param()?{ + if let Some(mut self_param) = self.parse_self_param()? { let self_attrs = self.parse_outer_attributes()?; self_param.attrs = self.attrs; params.push(self_param); From 26fd1bbca3cb632e4db0d0b3eb76dd7edbf3616f Mon Sep 17 00:00:00 2001 From: xonx <119700621+xonx4l@users.noreply.github.com> Date: Tue, 19 Aug 2025 09:11:58 +0530 Subject: [PATCH 4/4] Update item.rs --- compiler/rustc_parse/src/parser/item.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index cc37640df26d5..ba84c20e8fe42 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -2961,9 +2961,9 @@ impl<'a> Parser<'a> { let mut params = ThinVec::new(); // Parse the self parameter as first parameter + let attrs = self.parse_outer_attributes()?; if let Some(mut self_param) = self.parse_self_param()? { - let self_attrs = self.parse_outer_attributes()?; - self_param.attrs = self.attrs; + self_param.attrs = attrs; params.push(self_param); }