https://gcc.gnu.org/g:c84eccd00a5fb4a5f8700194390c3caf5250b3b9
commit r17-5688-gc84eccd00a5fb4a5f8700194390c3caf5250b3b9 Author: Utkarsh Bahuguna <[email protected]> Date: Fri Oct 16 02:07:59 2026 +0530 gccrs: Parse const blocks at the start of a statement Const blocks at the start of a statement were parsed as const items and failed. Parse them as expressions instead, like unsafe blocks. Addresses Rust-GCC/gccrs#4997 Assisted-by: Claude (Opus 5.5) for tests. gcc/rust/ChangeLog: * parse/rust-parse-impl.hxx (Parser::parse_stmt_or_expr): Parse const blocks as expressions. gcc/testsuite/ChangeLog: * rust/compile/const-items-in-block.rs: New test. * rust/compile/inline-const-bare.rs: New test. * rust/compile/inline-const-generic.rs: New test. * rust/compile/inline-const-stmt.rs: New test. * rust/execute/torture/inline-const-stmt.rs: New test. Signed-off-by: Utkarsh Bahuguna <[email protected]> Diff: --- gcc/rust/parse/rust-parse-impl.hxx | 9 ++++++++- gcc/testsuite/rust/compile/const-items-in-block.rs | 11 +++++++++++ gcc/testsuite/rust/compile/inline-const-bare.rs | 6 ++++++ gcc/testsuite/rust/compile/inline-const-generic.rs | 10 ++++++++++ gcc/testsuite/rust/compile/inline-const-stmt.rs | 19 +++++++++++++++++++ .../rust/execute/torture/inline-const-stmt.rs | 15 +++++++++++++++ 6 files changed, 69 insertions(+), 1 deletion(-) diff --git a/gcc/rust/parse/rust-parse-impl.hxx b/gcc/rust/parse/rust-parse-impl.hxx index 406da39fd830..38aa1b0ab36f 100644 --- a/gcc/rust/parse/rust-parse-impl.hxx +++ b/gcc/rust/parse/rust-parse-impl.hxx @@ -7233,6 +7233,14 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr () parse_let_stmt (std::move (outer_attrs))); return ExprOrStmt (std::move (stmt)); } + case CONST: + if (lexer.peek_token (1)->get_id () == LEFT_CURLY) + { + // const block: parse as expression + expr = parse_expr (std::move (outer_attrs), restrictions); + break; + } + gcc_fallthrough (); case PUB: case MOD: case EXTERN_KW: @@ -7241,7 +7249,6 @@ Parser<ManagedTokenSource>::parse_stmt_or_expr () case TYPE: case STRUCT_KW: case ENUM_KW: - case CONST: case STATIC_KW: case AUTO: case TRAIT: diff --git a/gcc/testsuite/rust/compile/const-items-in-block.rs b/gcc/testsuite/rust/compile/const-items-in-block.rs new file mode 100644 index 000000000000..edca1c7cc639 --- /dev/null +++ b/gcc/testsuite/rust/compile/const-items-in-block.rs @@ -0,0 +1,11 @@ +#![feature(no_core)] +#![no_core] + +fn main() -> i32 { + const fn one() -> i32 { + 1 + } + const X: i32 = 1; + + one() - X +} diff --git a/gcc/testsuite/rust/compile/inline-const-bare.rs b/gcc/testsuite/rust/compile/inline-const-bare.rs new file mode 100644 index 000000000000..cd1ac5261c69 --- /dev/null +++ b/gcc/testsuite/rust/compile/inline-const-bare.rs @@ -0,0 +1,6 @@ +#![feature(no_core)] +#![no_core] + +fn main() { + const; // { dg-error "unexpected token .;. in some sort of const production" } +} diff --git a/gcc/testsuite/rust/compile/inline-const-generic.rs b/gcc/testsuite/rust/compile/inline-const-generic.rs new file mode 100644 index 000000000000..e2d9b0acb53d --- /dev/null +++ b/gcc/testsuite/rust/compile/inline-const-generic.rs @@ -0,0 +1,10 @@ +#![feature(no_core)] +#![no_core] + +fn double<const N: usize>() -> usize { + const { N * 2 } +} + +fn main() { + double::<3>(); +} diff --git a/gcc/testsuite/rust/compile/inline-const-stmt.rs b/gcc/testsuite/rust/compile/inline-const-stmt.rs new file mode 100644 index 000000000000..50fbf63d4ee2 --- /dev/null +++ b/gcc/testsuite/rust/compile/inline-const-stmt.rs @@ -0,0 +1,19 @@ +#![feature(no_core)] +#![no_core] + +fn stmt() { + const { 1 + 1 }; + const { + let _a = 2; + } + let _b = 3; +} + +fn tail() -> i32 { + const { 1 + 1 } +} + +fn main() { + stmt(); + tail(); +} diff --git a/gcc/testsuite/rust/execute/torture/inline-const-stmt.rs b/gcc/testsuite/rust/execute/torture/inline-const-stmt.rs new file mode 100644 index 000000000000..a11369076fb5 --- /dev/null +++ b/gcc/testsuite/rust/execute/torture/inline-const-stmt.rs @@ -0,0 +1,15 @@ +#![feature(no_core)] +#![no_core] + +fn tail() -> i32 { + const { 1 + 1 } +} + +fn double<const N: i32>() -> i32 { + const { N * 2 } +} + +fn main() -> i32 { + const { 3 }; + tail() + double::<3>() - 8 +}
