Skip to content

Don't recover &raw EXPR as a missing comma#157079

Merged
rust-bors[bot] merged 5 commits into
rust-lang:mainfrom
qaijuang:raw-expr-list-recovery
Jun 12, 2026
Merged

Don't recover &raw EXPR as a missing comma#157079
rust-bors[bot] merged 5 commits into
rust-lang:mainfrom
qaijuang:raw-expr-list-recovery

Conversation

@qaijuang

@qaijuang qaijuang commented May 28, 2026

Copy link
Copy Markdown
Contributor

The parser already has a targeted suggestion for &raw EXPR, added in #139392, telling the user that &raw must be followed by const or mut.

In comma-separated expression lists, the generic missing-comma recovery would then treat the expression after raw as the next list element. That produced follow-up diagnostics like:

  • help: missing ','
  • cannot find value raw in this scope
  • an arity error for calls such as takes_raw_ptr(&raw x)

This PR avoids that comma recovery when we are already in the &raw missing-const/mut diagnostic path. For function calls, it preserves the call expression with a single error argument, so useful later diagnostics such as cannot find function f are still emitted.

Fixes #157015.

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels May 28, 2026
@qaijuang qaijuang marked this pull request as ready for review May 28, 2026 22:37
@rustbot

rustbot commented May 28, 2026

Copy link
Copy Markdown
Collaborator

The parser was modified, potentially altering the grammar of (stable) Rust
which would be a breaking change.

cc @fmease

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 28, 2026
@rustbot

rustbot commented May 28, 2026

Copy link
Copy Markdown
Collaborator

r? @jieyouxu

rustbot has assigned @jieyouxu.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 73 candidates
  • Random selection from 19 candidates

@jieyouxu

Copy link
Copy Markdown
Member

(Focusing on debuginfo/compiletest/rustfmt reviews this weekend)
@rustbot reroll

@rustbot rustbot assigned Kivooeo and unassigned jieyouxu May 29, 2026

@Kivooeo Kivooeo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread compiler/rustc_parse/src/parser/expr.rs Outdated
Comment on lines +1285 to +1288
if self.prev_token.is_keyword(kw::Raw)
&& self.expected_token_types.contains(TokenType::KwMut)
&& self.expected_token_types.contains(TokenType::KwConst)
&& self.token.can_begin_expr() =>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'd want to factor out this check into separate method like is_addr_of_missing_const_mut(&self) -> bool, or came up with better naming

@qaijuang qaijuang Jun 4, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had it in mind initially but needed validation like this.

given it'll be a parser/diagnostics method, name like is_expected_raw_ref_mut(&self) -> bool reads nicer with surrounding methods e.g the existing label_expected_raw_ref(&mut self, err: &mut Diag<'_>)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we also add a multi arguments test, like takes_raw_ptr(&raw x, x)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch! 🤦🏾‍♂️

@Kivooeo

Kivooeo commented Jun 5, 2026

Copy link
Copy Markdown
Member

hm, why this loop was introduced?

@qaijuang

qaijuang commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

hm, why this loop was introduced?

it's basically to preserve the argument count for multi arguments

@Kivooeo

Kivooeo commented Jun 5, 2026

Copy link
Copy Markdown
Member

how was the multi arguments diagnostics looked like without this last commit with loop

is that was buggy or something, need this understand what this is fixing

@qaijuang

qaijuang commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

how was the multi arguments diagnostics looked like without this last commit with loop

is that was buggy or something, need this understand what this is fixing

it was buggy in the sense that it failed the multi args test

@Kivooeo

Kivooeo commented Jun 5, 2026

Copy link
Copy Markdown
Member

i need to think more about this, so review might take some time

@Kivooeo

Kivooeo commented Jun 10, 2026

Copy link
Copy Markdown
Member

ok, here is what i think. let's add this helper

fn recover_raw_ref_call_args(&mut self, guar: ErrorGuaranteed) -> ThinVec<Box<Expr>> {
    let err_span = self.prev_token.span.to(self.token.span);
    let mut args = thin_vec![self.mk_expr_err(err_span, guar)];
    while self.token != token::Eof && self.token != token::CloseParen {
        if self.eat(exp!(Comma)) {
            if self.token != token::Eof && self.token != token::CloseParen {
                args.push(self.mk_expr_err(self.prev_token.span.shrink_to_hi(), guar));
            }
        } else {
            self.parse_token_tree();
        }
    }
    let _ = self.eat(exp!(CloseParen));
    args
}

and then call site's become this

Err(err) if self.is_expected_raw_ref_mut() => {
    let guar = err.emit();
    let args = self.recover_raw_ref_call_args(guar);
    return self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args));
}

can you try and verify it's work as intended

@qaijuang

Copy link
Copy Markdown
Contributor Author

ok, here is what i think. let's add this helper

fn recover_raw_ref_call_args(&mut self, guar: ErrorGuaranteed) -> ThinVec<Box<Expr>> {
    let err_span = self.prev_token.span.to(self.token.span);
    let mut args = thin_vec![self.mk_expr_err(err_span, guar)];
    while self.token != token::Eof && self.token != token::CloseParen {
        if self.eat(exp!(Comma)) {
            if self.token != token::Eof && self.token != token::CloseParen {
                args.push(self.mk_expr_err(self.prev_token.span.shrink_to_hi(), guar));
            }
        } else {
            self.parse_token_tree();
        }
    }
    let _ = self.eat(exp!(CloseParen));
    args
}

and then call site's become this

Err(err) if self.is_expected_raw_ref_mut() => {
    let guar = err.emit();
    let args = self.recover_raw_ref_call_args(guar);
    return self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args));
}

can you try and verify it's work as intended

Yes, it was part of my initial thought but I couldn’t think of its usefulness outside this issue?

@Kivooeo

Kivooeo commented Jun 10, 2026

Copy link
Copy Markdown
Member

its just keep code clean i guess

@Kivooeo

Kivooeo commented Jun 12, 2026

Copy link
Copy Markdown
Member

@bors r+ rollup

@rust-bors

rust-bors Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 68381b1 has been approved by Kivooeo

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 12, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jun 12, 2026
…=Kivooeo

Don't recover `&raw EXPR` as a missing comma

The parser already has a targeted suggestion for `&raw EXPR`, added in rust-lang#139392, telling the user that `&raw` must be followed by `const` or `mut`.

In comma-separated expression lists, the generic missing-comma recovery would then treat the expression after `raw` as the next list element. That produced follow-up diagnostics like:

- `help: missing ','`
- `cannot find value raw in this scope`
- an arity error for calls such as `takes_raw_ptr(&raw x)`

This PR avoids that comma recovery when we are already in the `&raw` missing-`const`/`mut` diagnostic path. For function calls, it preserves the call expression with a single error argument, so useful later diagnostics such as `cannot find function f` are still emitted.

Fixes rust-lang#157015.
rust-bors Bot pushed a commit that referenced this pull request Jun 12, 2026
…uwer

Rollup of 23 pull requests

Successful merges:

 - #144220 (Add powerpc64-unknown-linux-gnuelfv2 target)
 - #153238 (debuginfo: slices are DW_TAG_array_type's)
 - #157112 (Update aarch64-unknown-freebsd target description)
 - #157322 (test pre-stabilization items on CI)
 - #157348 (Don't track cwd for `-Zremap-cwd-prefix` in incremental compilation)
 - #157490 (Add field-wise CoerceShared reborrow tests)
 - #157655 (Make Share::share final and improve docs)
 - #157672 (Region inference: Simplify initialisation of region values)
 - #157680 (Require `#[pin_v2]` for explicit pin-projection patterns)
 - #157688 (Create experimental test job `aarch64-apple-macos-26` for evaluating `macos-26` runner images)
 - #157796 (rustdoc: Some more lazy formatting)
 - #157818 (miri subtree update)
 - #157069 (Test that you can't implement Unpin for a compiler-generated future using TAIT)
 - #157079 (Don't recover `&raw EXPR` as a missing comma)
 - #157202 (add #[rustc_no_writable] to slice::get_unchecked_mut)
 - #157622 (Disable retagging for variadic arguments in const-eval)
 - #157684 (-Zassumptions-on-binders: insert empty assumptions when entering binders in the solver)
 - #157695 (Extend capabilities of `TypeFoldable_Generic`)
 - #157766 (interpret: avoid computing layout of sized raw pointee)
 - #157785 (fuchsia: Support AddressSanitizer on riscv64gc-unknown-fuchsia)
 - #157795 (revert 157013)
 - #157798 (Prevent approving PRs that wait for Crater or formal decisions)
 - #157803 (Rename `errors.rs` file to `diagnostics.rs` (7/N))

Failed merges:

 - #157752 (Rename `errors.rs` file to `diagnostics.rs` (6/N))
@rust-bors rust-bors Bot merged commit 3f0676c into rust-lang:main Jun 12, 2026
12 checks passed
@rustbot rustbot added this to the 1.98.0 milestone Jun 12, 2026
@qaijuang qaijuang deleted the raw-expr-list-recovery branch June 13, 2026 00:51
pull Bot pushed a commit to xtqqczze/rust-lang-miri that referenced this pull request Jun 13, 2026
…uwer

Rollup of 23 pull requests

Successful merges:

 - rust-lang/rust#144220 (Add powerpc64-unknown-linux-gnuelfv2 target)
 - rust-lang/rust#153238 (debuginfo: slices are DW_TAG_array_type's)
 - rust-lang/rust#157112 (Update aarch64-unknown-freebsd target description)
 - rust-lang/rust#157322 (test pre-stabilization items on CI)
 - rust-lang/rust#157348 (Don't track cwd for `-Zremap-cwd-prefix` in incremental compilation)
 - rust-lang/rust#157490 (Add field-wise CoerceShared reborrow tests)
 - rust-lang/rust#157655 (Make Share::share final and improve docs)
 - rust-lang/rust#157672 (Region inference: Simplify initialisation of region values)
 - rust-lang/rust#157680 (Require `#[pin_v2]` for explicit pin-projection patterns)
 - rust-lang/rust#157688 (Create experimental test job `aarch64-apple-macos-26` for evaluating `macos-26` runner images)
 - rust-lang/rust#157796 (rustdoc: Some more lazy formatting)
 - rust-lang/rust#157818 (miri subtree update)
 - rust-lang/rust#157069 (Test that you can't implement Unpin for a compiler-generated future using TAIT)
 - rust-lang/rust#157079 (Don't recover `&raw EXPR` as a missing comma)
 - rust-lang/rust#157202 (add #[rustc_no_writable] to slice::get_unchecked_mut)
 - rust-lang/rust#157622 (Disable retagging for variadic arguments in const-eval)
 - rust-lang/rust#157684 (-Zassumptions-on-binders: insert empty assumptions when entering binders in the solver)
 - rust-lang/rust#157695 (Extend capabilities of `TypeFoldable_Generic`)
 - rust-lang/rust#157766 (interpret: avoid computing layout of sized raw pointee)
 - rust-lang/rust#157785 (fuchsia: Support AddressSanitizer on riscv64gc-unknown-fuchsia)
 - rust-lang/rust#157795 (revert 157013)
 - rust-lang/rust#157798 (Prevent approving PRs that wait for Crater or formal decisions)
 - rust-lang/rust#157803 (Rename `errors.rs` file to `diagnostics.rs` (7/N))

Failed merges:

 - rust-lang/rust#157752 (Rename `errors.rs` file to `diagnostics.rs` (6/N))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

&raw $expr in a list should not recover to &raw, $expr

4 participants