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
+}

Reply via email to