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);
}