Rollup merge of #141670 - chenyukang:yukang-fix-ice-from-contracts, r=nnethercote

Fix ICE in tokenstream with contracts from parser recovery

Fixes rust-lang/rust#140683

After two times of parsing error, the `recover_stmt_` constructs an error ast, then when we expand macors, the invalid tokenstream triggered ICE because of mismatched delims.

Expected `{` and get other tokens is an obvious error message, too much effort on recovery may introduce noise.

r? ```@nnethercote```
This commit is contained in:
Trevor Gross 2025-05-28 10:28:11 -04:00 committed by GitHub
commit d6b1108cda
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 60 additions and 26 deletions

View file

@ -515,8 +515,8 @@ impl<'a> Parser<'a> {
fn error_block_no_opening_brace_msg(&mut self, msg: Cow<'static, str>) -> Diag<'a> {
let prev = self.prev_token.span;
let sp = self.token.span;
let mut e = self.dcx().struct_span_err(sp, msg);
self.label_expected_raw_ref(&mut e);
let mut err = self.dcx().struct_span_err(sp, msg);
self.label_expected_raw_ref(&mut err);
let do_not_suggest_help = self.token.is_keyword(kw::In)
|| self.token == token::Colon
@ -558,20 +558,19 @@ impl<'a> Parser<'a> {
stmt.span
};
self.suggest_fixes_misparsed_for_loop_head(
&mut e,
&mut err,
prev.between(sp),
stmt_span,
&stmt.kind,
);
}
Err(e) => {
self.recover_stmt_(SemiColonMode::Break, BlockMode::Ignore);
e.cancel();
e.delay_as_bug();
}
_ => {}
}
e.span_label(sp, "expected `{`");
e
err.span_label(sp, "expected `{`");
err
}
fn suggest_fixes_misparsed_for_loop_head(

View file

@ -1,5 +0,0 @@
//@ known-bug: #140683
impl T {
#[core::contracts::ensures]
fn b() { (loop) }
}

View file

@ -0,0 +1,13 @@
#![feature(contracts)]
#![allow(incomplete_features)]
struct T;
impl T {
#[core::contracts::ensures] //~ ERROR expected a `Fn(&_)` closure, found `()`
fn b() {(loop)}
//~^ ERROR expected `{`, found `)`
//~| ERROR expected `{`, found `)`
}
fn main() {}

View file

@ -0,0 +1,34 @@
error: expected `{`, found `)`
--> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:8:18
|
LL | fn b() {(loop)}
| ----^ expected `{`
| |
| while parsing this `loop` expression
error: expected `{`, found `)`
--> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:8:18
|
LL | fn b() {(loop)}
| ----^ expected `{`
| |
| while parsing this `loop` expression
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error[E0277]: expected a `Fn(&_)` closure, found `()`
--> $DIR/ice-in-tokenstream-for-contracts-issue-140683.rs:7:5
|
LL | #[core::contracts::ensures]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| expected an `Fn(&_)` closure, found `()`
| required by a bound introduced by this call
|
= help: the trait `for<'a> Fn(&'a _)` is not implemented for `()`
note: required by a bound in `build_check_ensures`
--> $SRC_DIR/core/src/contracts.rs:LL:COL
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0277`.

View file

@ -2,9 +2,8 @@
macro_rules! m {
(static a : () = $e:expr) => {
static a : () = $e;
//~^ ERROR macro expansion ends with an incomplete expression: expected expression
}
static a: () = $e;
};
}
m! { static a : () = (if b) }

View file

@ -1,33 +1,27 @@
error: expected `{`, found `)`
--> $DIR/no-close-delim-issue-139248.rs:10:27
--> $DIR/no-close-delim-issue-139248.rs:9:27
|
LL | m! { static a : () = (if b) }
| ^ expected `{`
|
note: the `if` expression is missing a block after this condition
--> $DIR/no-close-delim-issue-139248.rs:10:26
--> $DIR/no-close-delim-issue-139248.rs:9:26
|
LL | m! { static a : () = (if b) }
| ^
error: expected `{`, found `)`
--> $DIR/no-close-delim-issue-139248.rs:10:27
--> $DIR/no-close-delim-issue-139248.rs:9:27
|
LL | m! { static a : () = (if b) }
| ^ expected `{`
|
note: the `if` expression is missing a block after this condition
--> $DIR/no-close-delim-issue-139248.rs:10:26
--> $DIR/no-close-delim-issue-139248.rs:9:26
|
LL | m! { static a : () = (if b) }
| ^
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
error: macro expansion ends with an incomplete expression: expected expression
--> $DIR/no-close-delim-issue-139248.rs:5:28
|
LL | static a : () = $e;
| ^ expected expression
error: aborting due to 3 previous errors
error: aborting due to 2 previous errors