Skip to content

Commit 243521a

Browse files
Rollup merge of rust-lang#157888 - TaKO8Ki:fix-raw-ref-nested-call-arg-recover, r=folkertdev
Avoid `&raw` call recovery inside nested delimiters Fixes rust-lang#157853 The `&raw <expr>` recovery is only valid for malformed raw refs directly in the call argument list. When it handled the nested array case, it tried to skip tokens until the call's ), reached the nested ], and could ICE in parse_token_tree. This PR scopes the call-argument recovery to the call's delimiter depth and makes the recovery loop stop before any closing delimiter or EOF.
2 parents 0a4ee11 + 33d1436 commit 243521a

3 files changed

Lines changed: 28 additions & 4 deletions

File tree

compiler/rustc_parse/src/parser/expr.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1278,10 +1278,14 @@ impl<'a> Parser<'a> {
12781278
None
12791279
};
12801280
let open_paren = self.token.span;
1281+
let call_depth = self.token_cursor.stack.len();
12811282

12821283
let seq = match self.parse_expr_paren_seq() {
12831284
Ok(args) => Ok(self.mk_expr(lo.to(self.prev_token.span), self.mk_call(fun, args))),
1284-
Err(err) if self.is_expected_raw_ref_mut() => {
1285+
Err(err)
1286+
if self.is_expected_raw_ref_mut()
1287+
&& self.token_cursor.stack.len() == call_depth =>
1288+
{
12851289
let guar = err.emit();
12861290
// Preserve the call expression so later passes can still diagnose the callee,
12871291
// while treating the malformed `&raw <expr>` argument as an error expression.
@@ -1299,9 +1303,8 @@ impl<'a> Parser<'a> {
12991303
fn recover_raw_ref_call_args(&mut self, guar: ErrorGuaranteed) -> ThinVec<Box<Expr>> {
13001304
let err_span = self.prev_token.span.to(self.token.span);
13011305
let mut args = thin_vec![self.mk_expr_err(err_span, guar)];
1302-
while self.token != token::Eof && self.token != token::CloseParen {
1303-
if self.eat(exp!(Comma)) && self.token != token::Eof && self.token != token::CloseParen
1304-
{
1306+
while !self.token.kind.is_close_delim_or_eof() {
1307+
if self.eat(exp!(Comma)) && !self.token.kind.is_close_delim_or_eof() {
13051308
args.push(self.mk_expr_err(self.prev_token.span.shrink_to_hi(), guar));
13061309
} else {
13071310
self.parse_token_tree();
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Regression test for https://github.com/rust-lang/rust/issues/157853.
2+
3+
fn main() {
4+
Test([&raw 2])
5+
//~^ ERROR expected one of
6+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error: expected one of `!`, `,`, `.`, `::`, `;`, `?`, `]`, `const`, `mut`, `{`, or an operator, found `2`
2+
--> $DIR/raw-no-const-mut-nested-call-arg.rs:4:16
3+
|
4+
LL | Test([&raw 2])
5+
| ^ expected one of 11 possible tokens
6+
|
7+
help: `&raw` must be followed by `const` or `mut` to be a raw reference expression
8+
|
9+
LL | Test([&raw const 2])
10+
| +++++
11+
LL | Test([&raw mut 2])
12+
| +++
13+
14+
error: aborting due to 1 previous error
15+

0 commit comments

Comments
 (0)