From adcd0bf5c36ee49acf390f0d75125da4efda35ac Mon Sep 17 00:00:00 2001 From: yukang Date: Wed, 28 May 2025 09:34:08 +0800 Subject: [PATCH] Fix ICE in tokenstream with contracts from parser recovery --- compiler/rustc_parse/src/parser/stmt.rs | 13 ++++--- tests/crashes/140683.rs | 5 --- ...-tokenstream-for-contracts-issue-140683.rs | 13 +++++++ ...enstream-for-contracts-issue-140683.stderr | 34 +++++++++++++++++++ .../ui/macros/no-close-delim-issue-139248.rs | 5 ++- .../macros/no-close-delim-issue-139248.stderr | 16 +++------ 6 files changed, 60 insertions(+), 26 deletions(-) delete mode 100644 tests/crashes/140683.rs create mode 100644 tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.rs create mode 100644 tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.stderr diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 396ded96bde13..ccc3410674b46 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -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( diff --git a/tests/crashes/140683.rs b/tests/crashes/140683.rs deleted file mode 100644 index 74ea5c2533bb9..0000000000000 --- a/tests/crashes/140683.rs +++ /dev/null @@ -1,5 +0,0 @@ -//@ known-bug: #140683 -impl T { -#[core::contracts::ensures] - fn b() { (loop) } -} diff --git a/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.rs b/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.rs new file mode 100644 index 0000000000000..68346a00ae1a7 --- /dev/null +++ b/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.rs @@ -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() {} diff --git a/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.stderr b/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.stderr new file mode 100644 index 0000000000000..f1ffda2a9bee6 --- /dev/null +++ b/tests/ui/macros/ice-in-tokenstream-for-contracts-issue-140683.stderr @@ -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`. diff --git a/tests/ui/macros/no-close-delim-issue-139248.rs b/tests/ui/macros/no-close-delim-issue-139248.rs index 86583b2724ed0..f15234eaff1a7 100644 --- a/tests/ui/macros/no-close-delim-issue-139248.rs +++ b/tests/ui/macros/no-close-delim-issue-139248.rs @@ -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) } diff --git a/tests/ui/macros/no-close-delim-issue-139248.stderr b/tests/ui/macros/no-close-delim-issue-139248.stderr index 6ed41ae9b46a6..8aa39851b4b0f 100644 --- a/tests/ui/macros/no-close-delim-issue-139248.stderr +++ b/tests/ui/macros/no-close-delim-issue-139248.stderr @@ -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