https://gcc.gnu.org/g:70fab4b0ce318ca7de67f5f26726ff5d403025f3

commit 70fab4b0ce318ca7de67f5f26726ff5d403025f3
Author: Arthur Cohen <arthur.co...@embecosm.com>
Date:   Tue Apr 15 13:34:38 2025 +0200

    hir: Add const blocks
    
    gcc/rust/ChangeLog:
    
            * hir/tree/rust-hir-expr.h: New classes.
            * hir/tree/rust-hir-full-decls.h: Likewise.
            * hir/tree/rust-hir.cc: Handle AnonConst and ConstBlock.
            * backend/rust-compile-block.cc: Likewise.
            * backend/rust-compile-block.h: Likewise.
            * backend/rust-compile-expr.cc (CompileExpr::visit): Likewise.
            * backend/rust-compile-expr.h: Likewise.
            * checks/errors/borrowck/rust-bir-builder-expr-stmt.cc 
(ExprStmtBuilder::visit): Likewise.
            * checks/errors/borrowck/rust-bir-builder-expr-stmt.h: Likewise.
            * checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h: Likewise.
            * checks/errors/borrowck/rust-bir-builder-struct.h: Likewise.
            * checks/errors/borrowck/rust-function-collector.h: Likewise.
            * checks/errors/privacy/rust-privacy-reporter.cc 
(PrivacyReporter::visit): Likewise.
            * checks/errors/privacy/rust-privacy-reporter.h: Likewise.
            * checks/errors/rust-const-checker.cc (ConstChecker::visit): 
Likewise.
            * checks/errors/rust-const-checker.h: Likewise.
            * checks/errors/rust-hir-pattern-analysis.cc 
(PatternChecker::visit): Likewise.
            * checks/errors/rust-hir-pattern-analysis.h: Likewise.
            * checks/errors/rust-unsafe-checker.cc (UnsafeChecker::visit): 
Likewise.
            * checks/errors/rust-unsafe-checker.h: Likewise.
            * hir/rust-ast-lower-expr.cc (ASTLoweringExpr::visit): Likewise.
            (translate_operand_out): Likewise.
            (translate_operand_inout): Likewise.
            (translate_operand_const): Likewise.
            * hir/rust-ast-lower-expr.h: Likewise.
            * hir/rust-hir-dump.cc (Dump::visit): Likewise.
            * hir/rust-hir-dump.h: Likewise.
            * hir/tree/rust-hir-expr-abstract.h: Likewise.
            * hir/tree/rust-hir-expr.cc (AnonConst::AnonConst): Likewise.
            (AnonConst::operator=): Likewise.
            (ConstBlock::ConstBlock): Likewise.
            (ConstBlock::operator=): Likewise.
            * hir/tree/rust-hir-visitor.h:
            * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit): 
Likewise.
            (typecheck_inline_asm_operand): Likewise.
            * typecheck/rust-hir-type-check-expr.h: Likewise.

Diff:
---
 gcc/rust/backend/rust-compile-block.cc             |  1 +
 gcc/rust/backend/rust-compile-block.h              |  9 +++
 gcc/rust/backend/rust-compile-expr.cc              | 13 ++++
 gcc/rust/backend/rust-compile-expr.h               |  2 +
 .../errors/borrowck/rust-bir-builder-expr-stmt.cc  | 12 ++++
 .../errors/borrowck/rust-bir-builder-expr-stmt.h   |  2 +
 .../borrowck/rust-bir-builder-lazyboolexpr.h       |  8 +++
 .../errors/borrowck/rust-bir-builder-struct.h      |  2 +
 .../errors/borrowck/rust-function-collector.h      |  2 +
 .../checks/errors/privacy/rust-privacy-reporter.cc | 12 ++++
 .../checks/errors/privacy/rust-privacy-reporter.h  |  2 +
 gcc/rust/checks/errors/rust-const-checker.cc       | 20 ++++++
 gcc/rust/checks/errors/rust-const-checker.h        |  2 +
 .../checks/errors/rust-hir-pattern-analysis.cc     | 12 ++++
 gcc/rust/checks/errors/rust-hir-pattern-analysis.h |  2 +
 gcc/rust/checks/errors/rust-unsafe-checker.cc      | 12 ++++
 gcc/rust/checks/errors/rust-unsafe-checker.h       |  2 +
 gcc/rust/hir/rust-ast-lower-expr.cc                | 60 +++++++++++++---
 gcc/rust/hir/rust-ast-lower-expr.h                 |  2 +
 gcc/rust/hir/rust-hir-dump.cc                      | 22 ++++++
 gcc/rust/hir/rust-hir-dump.h                       |  2 +
 gcc/rust/hir/tree/rust-hir-expr-abstract.h         |  4 +-
 gcc/rust/hir/tree/rust-hir-expr.cc                 | 64 ++++++++++++------
 gcc/rust/hir/tree/rust-hir-expr.h                  | 79 ++++++++++++++++++----
 gcc/rust/hir/tree/rust-hir-full-decls.h            |  3 +-
 gcc/rust/hir/tree/rust-hir-visitor.h               |  6 ++
 gcc/rust/hir/tree/rust-hir.cc                      | 51 ++++++++++++++
 gcc/rust/typecheck/rust-hir-type-check-expr.cc     | 14 +++-
 gcc/rust/typecheck/rust-hir-type-check-expr.h      |  2 +
 29 files changed, 380 insertions(+), 44 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-block.cc 
b/gcc/rust/backend/rust-compile-block.cc
index 56d0c417f0ab..b55fe68ca940 100644
--- a/gcc/rust/backend/rust-compile-block.cc
+++ b/gcc/rust/backend/rust-compile-block.cc
@@ -19,6 +19,7 @@
 #include "rust-compile-block.h"
 #include "rust-compile-stmt.h"
 #include "rust-compile-expr.h"
+#include "rust-hir-expr.h"
 
 namespace Rust {
 namespace Compile {
diff --git a/gcc/rust/backend/rust-compile-block.h 
b/gcc/rust/backend/rust-compile-block.h
index 896ff7584421..e288bd89f261 100644
--- a/gcc/rust/backend/rust-compile-block.h
+++ b/gcc/rust/backend/rust-compile-block.h
@@ -83,6 +83,8 @@ public:
   void visit (HIR::MethodCallExpr &) override {}
   void visit (HIR::FieldAccessExpr &) override {}
   void visit (HIR::BlockExpr &) override {}
+  void visit (HIR::AnonConst &) override {}
+  void visit (HIR::ConstBlock &) override {}
   void visit (HIR::ContinueExpr &) override {}
   void visit (HIR::BreakExpr &) override {}
   void visit (HIR::RangeFromToExpr &) override {}
@@ -138,6 +140,12 @@ public:
     translated = CompileBlock::compile (expr, ctx, result);
   }
 
+  void visit (HIR::ConstBlock &expr) override
+  {
+    rust_unreachable ();
+    // translated = CompileExpr::compile (expr, ctx, result);
+  }
+
   // Empty visit for unused Expression HIR nodes.
   void visit (HIR::PathInExpression &) override {}
   void visit (HIR::QualifiedPathInExpression &) override {}
@@ -184,6 +192,7 @@ public:
   void visit (HIR::AsyncBlockExpr &) override {}
   void visit (HIR::InlineAsm &) override {}
   void visit (HIR::LlvmInlineAsm &) override {}
+  void visit (HIR::AnonConst &) override {}
 
 private:
   CompileExprWithBlock (Context *ctx, Bvariable *result)
diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index 339317d81747..0f633100ad43 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -30,6 +30,7 @@
 #include "realmpfr.h"
 #include "convert.h"
 #include "print-tree.h"
+#include "rust-hir-expr.h"
 #include "rust-system.h"
 #include "rust-tyty.h"
 
@@ -440,6 +441,18 @@ CompileExpr::visit (HIR::BlockExpr &expr)
   translated = Backend::var_expression (tmp, expr.get_locus ());
 }
 
+void
+CompileExpr::visit (HIR::AnonConst &expr)
+{
+  expr.get_inner_expr ().accept_vis (*this);
+}
+
+void
+CompileExpr::visit (HIR::ConstBlock &expr)
+{
+  expr.get_const_expr ().accept_vis (*this);
+}
+
 void
 CompileExpr::visit (HIR::UnsafeBlockExpr &expr)
 {
diff --git a/gcc/rust/backend/rust-compile-expr.h 
b/gcc/rust/backend/rust-compile-expr.h
index a9c59ab71398..fda508ddb558 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -48,6 +48,8 @@ public:
   void visit (HIR::IfExpr &expr) override;
   void visit (HIR::IfExprConseqElse &expr) override;
   void visit (HIR::BlockExpr &expr) override;
+  void visit (HIR::AnonConst &expr) override;
+  void visit (HIR::ConstBlock &expr) override;
   void visit (HIR::UnsafeBlockExpr &expr) override;
   void visit (HIR::StructExprStruct &struct_expr) override;
   void visit (HIR::StructExprStructFields &struct_expr) override;
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
index 70ad7ed21a5b..406b5a233a09 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.cc
@@ -414,6 +414,18 @@ ExprStmtBuilder::visit (HIR::BlockExpr &block)
     ctx.place_db.pop_scope ();
 }
 
+void
+ExprStmtBuilder::visit (HIR::AnonConst &block)
+{
+  rust_unreachable ();
+}
+
+void
+ExprStmtBuilder::visit (HIR::ConstBlock &block)
+{
+  rust_unreachable ();
+}
+
 void
 ExprStmtBuilder::visit (HIR::ContinueExpr &cont)
 {
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h
index 48b81991e07d..0db44e179072 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-expr-stmt.h
@@ -84,6 +84,8 @@ protected: // Expr
   void visit (HIR::MethodCallExpr &expr) override;
   void visit (HIR::FieldAccessExpr &expr) override;
   void visit (HIR::BlockExpr &block) override;
+  void visit (HIR::AnonConst &block) override;
+  void visit (HIR::ConstBlock &block) override;
   void visit (HIR::ContinueExpr &cont) override;
   void visit (HIR::BreakExpr &brk) override;
   void visit (HIR::RangeFromToExpr &range) override;
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
index dbf365a34789..31adca10b5f9 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-lazyboolexpr.h
@@ -169,6 +169,14 @@ public:
   {
     return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
   }
+  void visit (HIR::AnonConst &expr) override
+  {
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
+  }
+  void visit (HIR::ConstBlock &expr) override
+  {
+    return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
+  }
   void visit (HIR::UnsafeBlockExpr &expr) override
   {
     return_place (ExprStmtBuilder (ctx).build (expr), expr.get_locus ());
diff --git a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h 
b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
index fdec3291acd3..a689eda845f0 100644
--- a/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
+++ b/gcc/rust/checks/errors/borrowck/rust-bir-builder-struct.h
@@ -133,6 +133,8 @@ protected:
   void visit (HIR::MethodCallExpr &expr) override { rust_unreachable (); }
   void visit (HIR::FieldAccessExpr &expr) override { rust_unreachable (); }
   void visit (HIR::BlockExpr &expr) override { rust_unreachable (); }
+  void visit (HIR::AnonConst &expr) override { rust_unreachable (); }
+  void visit (HIR::ConstBlock &expr) override { rust_unreachable (); }
   void visit (HIR::ClosureExpr &expr) override { rust_unreachable (); }
   void visit (HIR::ContinueExpr &expr) override { rust_unreachable (); }
   void visit (HIR::BreakExpr &expr) override { rust_unreachable (); }
diff --git a/gcc/rust/checks/errors/borrowck/rust-function-collector.h 
b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
index 74b5f4365c1c..67a2c1a83526 100644
--- a/gcc/rust/checks/errors/borrowck/rust-function-collector.h
+++ b/gcc/rust/checks/errors/borrowck/rust-function-collector.h
@@ -104,6 +104,8 @@ public:
   void visit (HIR::MethodCallExpr &expr) override {}
   void visit (HIR::FieldAccessExpr &expr) override {}
   void visit (HIR::BlockExpr &expr) override {}
+  void visit (HIR::AnonConst &expr) override {}
+  void visit (HIR::ConstBlock &expr) override {}
   void visit (HIR::ContinueExpr &expr) override {}
   void visit (HIR::BreakExpr &expr) override {}
   void visit (HIR::RangeFromToExpr &expr) override {}
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc 
b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
index 4a5a6aa7cf19..903c131aed1f 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.cc
@@ -518,6 +518,18 @@ PrivacyReporter::visit (HIR::BlockExpr &expr)
     expr.get_final_expr ().accept_vis (*this);
 }
 
+void
+PrivacyReporter::visit (HIR::AnonConst &expr)
+{
+  expr.get_inner_expr ().accept_vis (*this);
+}
+
+void
+PrivacyReporter::visit (HIR::ConstBlock &expr)
+{
+  expr.get_const_expr ().accept_vis (*this);
+}
+
 void
 PrivacyReporter::visit (HIR::ContinueExpr &)
 {}
diff --git a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h 
b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
index c3d9f3011f90..d38854fdd192 100644
--- a/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
+++ b/gcc/rust/checks/errors/privacy/rust-privacy-reporter.h
@@ -106,6 +106,8 @@ types
   virtual void visit (HIR::MethodCallExpr &expr);
   virtual void visit (HIR::FieldAccessExpr &expr);
   virtual void visit (HIR::BlockExpr &expr);
+  virtual void visit (HIR::AnonConst &expr);
+  virtual void visit (HIR::ConstBlock &expr);
   virtual void visit (HIR::ContinueExpr &expr);
   virtual void visit (HIR::BreakExpr &expr);
   virtual void visit (HIR::RangeFromToExpr &expr);
diff --git a/gcc/rust/checks/errors/rust-const-checker.cc 
b/gcc/rust/checks/errors/rust-const-checker.cc
index 7423b82779a3..4e1084712378 100644
--- a/gcc/rust/checks/errors/rust-const-checker.cc
+++ b/gcc/rust/checks/errors/rust-const-checker.cc
@@ -416,6 +416,26 @@ ConstChecker::visit (BlockExpr &expr)
     expr.get_final_expr ().accept_vis (*this);
 }
 
+void
+ConstChecker::visit (AnonConst &expr)
+{
+  const_context.enter (expr.get_mappings ().get_hirid ());
+
+  expr.get_inner_expr ().accept_vis (*this);
+
+  const_context.exit ();
+}
+
+void
+ConstChecker::visit (ConstBlock &expr)
+{
+  const_context.enter (expr.get_mappings ().get_hirid ());
+
+  expr.get_const_expr ().accept_vis (*this);
+
+  const_context.exit ();
+}
+
 void
 ConstChecker::visit (ContinueExpr &)
 {}
diff --git a/gcc/rust/checks/errors/rust-const-checker.h 
b/gcc/rust/checks/errors/rust-const-checker.h
index 33f956ac0e5d..90cfebd59ec3 100644
--- a/gcc/rust/checks/errors/rust-const-checker.h
+++ b/gcc/rust/checks/errors/rust-const-checker.h
@@ -113,6 +113,8 @@ private:
   virtual void visit (FieldAccessExpr &expr) override;
   virtual void visit (ClosureExpr &expr) override;
   virtual void visit (BlockExpr &expr) override;
+  virtual void visit (AnonConst &expr) override;
+  virtual void visit (ConstBlock &expr) override;
   virtual void visit (ContinueExpr &expr) override;
   virtual void visit (BreakExpr &expr) override;
   virtual void visit (RangeFromToExpr &expr) override;
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc 
b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index 648bc07762db..8cff8e6c5d4e 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -294,6 +294,18 @@ PatternChecker::visit (BlockExpr &expr)
     expr.get_final_expr ().accept_vis (*this);
 }
 
+void
+PatternChecker::visit (AnonConst &expr)
+{
+  expr.get_inner_expr ().accept_vis (*this);
+}
+
+void
+PatternChecker::visit (ConstBlock &expr)
+{
+  expr.get_const_expr ().accept_vis (*this);
+}
+
 void
 PatternChecker::visit (ContinueExpr &)
 {}
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h 
b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
index 6d60ceda5384..620b07920486 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.h
@@ -86,6 +86,8 @@ private:
   virtual void visit (MethodCallExpr &expr) override;
   virtual void visit (FieldAccessExpr &expr) override;
   virtual void visit (BlockExpr &expr) override;
+  virtual void visit (AnonConst &expr) override;
+  virtual void visit (ConstBlock &expr) override;
   virtual void visit (ClosureExpr &expr) override;
   virtual void visit (ContinueExpr &expr) override;
   virtual void visit (BreakExpr &expr) override;
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.cc 
b/gcc/rust/checks/errors/rust-unsafe-checker.cc
index 7097c5000352..1cc618f02583 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.cc
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.cc
@@ -539,6 +539,18 @@ UnsafeChecker::visit (BlockExpr &expr)
     expr.get_final_expr ().accept_vis (*this);
 }
 
+void
+UnsafeChecker::visit (AnonConst &expr)
+{
+  expr.get_inner_expr ().accept_vis (*this);
+}
+
+void
+UnsafeChecker::visit (ConstBlock &expr)
+{
+  expr.get_const_expr ().accept_vis (*this);
+}
+
 void
 UnsafeChecker::visit (ContinueExpr &)
 {}
diff --git a/gcc/rust/checks/errors/rust-unsafe-checker.h 
b/gcc/rust/checks/errors/rust-unsafe-checker.h
index 7f5388c8e18d..a77de824f21a 100644
--- a/gcc/rust/checks/errors/rust-unsafe-checker.h
+++ b/gcc/rust/checks/errors/rust-unsafe-checker.h
@@ -95,6 +95,8 @@ private:
   virtual void visit (FieldAccessExpr &expr) override;
   virtual void visit (ClosureExpr &expr) override;
   virtual void visit (BlockExpr &expr) override;
+  virtual void visit (AnonConst &expr) override;
+  virtual void visit (ConstBlock &expr) override;
   virtual void visit (ContinueExpr &expr) override;
   virtual void visit (BreakExpr &expr) override;
   virtual void visit (RangeFromToExpr &expr) override;
diff --git a/gcc/rust/hir/rust-ast-lower-expr.cc 
b/gcc/rust/hir/rust-ast-lower-expr.cc
index 3dee87e17b63..d5aef7ed0700 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.cc
+++ b/gcc/rust/hir/rust-ast-lower-expr.cc
@@ -25,6 +25,7 @@
 #include "rust-ast-lower-type.h"
 #include "rust-ast.h"
 #include "rust-diagnostics.h"
+#include "rust-hir-map.h"
 #include "rust-system.h"
 #include "tree/rust-hir-expr.h"
 
@@ -126,6 +127,43 @@ ASTLoweringExpr::visit (AST::BlockExpr &expr)
   translated = ASTLoweringBlock::translate (expr, &terminated);
 }
 
+void
+ASTLoweringExpr::visit (AST::AnonConst &expr)
+{
+  auto inner_expr = ASTLoweringExpr::translate (expr.get_inner_expr ());
+
+  auto &mappings = Analysis::Mappings::get ();
+  auto crate_num = mappings.get_current_crate ();
+  auto mapping = Analysis::NodeMapping (crate_num, expr.get_node_id (),
+                                       mappings.get_next_hir_id (crate_num),
+                                       UNKNOWN_LOCAL_DEFID);
+
+  translated = new HIR::AnonConst (std::move (mapping),
+                                  std::unique_ptr<Expr> (inner_expr),
+                                  expr.get_locus ());
+}
+
+void
+ASTLoweringExpr::visit (AST::ConstBlock &expr)
+{
+  auto inner_expr = ASTLoweringExpr::translate (expr.get_const_expr ());
+
+  // we know this will always be an `AnonConst`, or we have an issue. Let's
+  // assert just to be sure.
+  rust_assert (inner_expr->get_expression_type () == 
Expr::ExprType::AnonConst);
+  auto anon_const = static_cast<AnonConst *> (inner_expr);
+
+  auto &mappings = Analysis::Mappings::get ();
+  auto crate_num = mappings.get_current_crate ();
+  auto mapping = Analysis::NodeMapping (crate_num, expr.get_node_id (),
+                                       mappings.get_next_hir_id (crate_num),
+                                       UNKNOWN_LOCAL_DEFID);
+
+  translated
+    = new HIR::ConstBlock (std::move (mapping), std::move (*anon_const),
+                          expr.get_locus (), expr.get_outer_attrs ());
+}
+
 void
 ASTLoweringExpr::visit (AST::UnsafeBlockExpr &expr)
 {
@@ -841,6 +879,7 @@ translate_operand_out (const AST::InlineAsmOperand &operand)
                                             *out_value.expr.get ())));
   return out;
 }
+
 HIR::InlineAsmOperand
 translate_operand_inout (const AST::InlineAsmOperand &operand)
 {
@@ -851,6 +890,7 @@ translate_operand_inout (const AST::InlineAsmOperand 
&operand)
                                                 *inout_value.expr.get ())));
   return inout;
 }
+
 HIR::InlineAsmOperand
 translate_operand_split_in_out (const AST::InlineAsmOperand &operand)
 {
@@ -863,19 +903,21 @@ translate_operand_split_in_out (const 
AST::InlineAsmOperand &operand)
       ASTLoweringExpr::translate (*split_in_out_value.out_expr.get ())));
   return split_in_out;
 }
+
 HIR::InlineAsmOperand
 translate_operand_const (const AST::InlineAsmOperand &operand)
 {
   auto const_value = operand.get_const ();
-  struct HIR::AnonConst anon_const (
-    const_value.anon_const.get_node_id (),
-    std::unique_ptr<Expr> (
-      ASTLoweringExpr::translate (const_value.anon_const.get_inner_expr ())));
-  struct HIR::InlineAsmOperand::Const cnst
-  {
-    anon_const
-  };
-  return cnst;
+
+  auto inner_expr = ASTLoweringExpr::translate (const_value.anon_const);
+
+  // Like `ConstBlock`, we know this should only be an `AnonConst` - let's
+  // assert to make sure and static cast
+  rust_assert (inner_expr->get_expression_type () == 
Expr::ExprType::AnonConst);
+
+  auto anon_const = static_cast<AnonConst *> (inner_expr);
+
+  return HIR::InlineAsmOperand::Const{*anon_const};
 }
 
 HIR::InlineAsmOperand
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h 
b/gcc/rust/hir/rust-ast-lower-expr.h
index b8681fb07cad..231217d1dea0 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -82,6 +82,8 @@ public:
   void visit (AST::IfLetExpr &expr) override;
   void visit (AST::IfLetExprConseqElse &expr) override;
   void visit (AST::BlockExpr &expr) override;
+  void visit (AST::AnonConst &expr) override;
+  void visit (AST::ConstBlock &expr) override;
   void visit (AST::UnsafeBlockExpr &expr) override;
   void visit (AST::PathInExpression &expr) override;
   void visit (AST::QualifiedPathInExpression &expr) override;
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index 156bd8139075..b91eaab1ebb2 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -1296,6 +1296,28 @@ Dump::visit (BlockExpr &e)
   end ("BlockExpr");
 }
 
+void
+Dump::visit (AnonConst &e)
+{
+  begin ("AnonConst");
+  do_expr (e);
+
+  visit_field ("inner", e.get_inner_expr ());
+
+  end ("AnonConst");
+}
+
+void
+Dump::visit (ConstBlock &e)
+{
+  begin ("ConstBlock");
+  do_expr (e);
+
+  visit_field ("inner", e.get_const_expr ());
+
+  end ("ConstBlock");
+}
+
 void
 Dump::visit (ContinueExpr &e)
 {
diff --git a/gcc/rust/hir/rust-hir-dump.h b/gcc/rust/hir/rust-hir-dump.h
index b3015c639cf2..119a09800446 100644
--- a/gcc/rust/hir/rust-hir-dump.h
+++ b/gcc/rust/hir/rust-hir-dump.h
@@ -146,6 +146,8 @@ private:
   virtual void visit (FieldAccessExpr &) override;
   virtual void visit (ClosureExpr &) override;
   virtual void visit (BlockExpr &) override;
+  virtual void visit (AnonConst &) override;
+  virtual void visit (ConstBlock &) override;
   virtual void visit (ContinueExpr &) override;
   virtual void visit (BreakExpr &) override;
   virtual void visit (RangeFromToExpr &) override;
diff --git a/gcc/rust/hir/tree/rust-hir-expr-abstract.h 
b/gcc/rust/hir/tree/rust-hir-expr-abstract.h
index 5bc5d8903099..8272a82808c9 100644
--- a/gcc/rust/hir/tree/rust-hir-expr-abstract.h
+++ b/gcc/rust/hir/tree/rust-hir-expr-abstract.h
@@ -43,7 +43,7 @@ public:
     WITHOUT_BLOCK,
   };
 
-  enum ExprType
+  enum class ExprType
   {
     Lit,
     Operator,
@@ -58,6 +58,8 @@ public:
     FieldAccess,
     Closure,
     Block,
+    AnonConst,
+    ConstBlock,
     Continue,
     Break,
     Range,
diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc 
b/gcc/rust/hir/tree/rust-hir-expr.cc
index 5df9253aae21..93dcec2c8d79 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.cc
+++ b/gcc/rust/hir/tree/rust-hir-expr.cc
@@ -790,6 +790,50 @@ BlockExpr::operator= (BlockExpr const &other)
   return *this;
 }
 
+AnonConst::AnonConst (Analysis::NodeMapping mappings,
+                     std::unique_ptr<Expr> &&expr, location_t locus)
+  : ExprWithBlock (std::move (mappings), {}), locus (locus),
+    expr (std::move (expr))
+{
+  rust_assert (this->expr);
+}
+
+AnonConst::AnonConst (const AnonConst &other)
+  : ExprWithBlock (other), locus (other.locus), expr (other.expr->clone_expr 
())
+{}
+
+AnonConst
+AnonConst::operator= (const AnonConst &other)
+{
+  ExprWithBlock::operator= (other);
+
+  locus = other.locus;
+  expr = other.expr->clone_expr ();
+
+  return *this;
+}
+
+ConstBlock::ConstBlock (Analysis::NodeMapping mappings, AnonConst &&expr,
+                       location_t locus, AST::AttrVec outer_attrs)
+  : ExprWithBlock (std::move (mappings), std::move (outer_attrs)),
+    expr (std::move (expr)), locus (locus)
+{}
+
+ConstBlock::ConstBlock (const ConstBlock &other)
+  : ExprWithBlock (other), expr (other.expr), locus (other.locus)
+{}
+
+ConstBlock
+ConstBlock::operator= (const ConstBlock &other)
+{
+  ExprWithBlock::operator= (other);
+
+  expr = other.expr;
+  locus = other.locus;
+
+  return *this;
+}
+
 ContinueExpr::ContinueExpr (Analysis::NodeMapping mappings, location_t locus,
                            tl::optional<Lifetime> label,
                            AST::AttrVec outer_attribs)
@@ -1310,26 +1354,6 @@ OperatorExprMeta::OperatorExprMeta (HIR::ComparisonExpr 
&expr)
     locus (expr.get_locus ())
 {}
 
-AnonConst::AnonConst (NodeId id, std::unique_ptr<Expr> expr)
-  : id (id), expr (std::move (expr))
-{
-  rust_assert (this->expr != nullptr);
-}
-
-AnonConst::AnonConst (const AnonConst &other)
-{
-  id = other.id;
-  expr = other.expr->clone_expr ();
-}
-
-AnonConst
-AnonConst::operator= (const AnonConst &other)
-{
-  id = other.id;
-  expr = other.expr->clone_expr ();
-  return *this;
-}
-
 InlineAsmOperand::In::In (
   const tl::optional<struct AST::InlineAsmRegOrRegClass> &reg,
   std::unique_ptr<Expr> expr)
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h 
b/gcc/rust/hir/tree/rust-hir-expr.h
index 77e742a2d386..ae25d52d6dfc 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -19,12 +19,14 @@
 #ifndef RUST_HIR_EXPR_H
 #define RUST_HIR_EXPR_H
 
+#include "rust-ast.h"
 #include "rust-hir-expr-abstract.h"
 #include "rust-hir-literal.h"
 #include "rust-common.h"
 #include "rust-hir-bound.h"
 #include "rust-hir-attrs.h"
 #include "rust-expr.h"
+#include "rust-hir-map.h"
 
 namespace Rust {
 namespace HIR {
@@ -1800,6 +1802,71 @@ protected:
   }
 };
 
+class AnonConst : public ExprWithBlock
+{
+public:
+  AnonConst (Analysis::NodeMapping mappings, std::unique_ptr<Expr> &&expr,
+            location_t locus = UNKNOWN_LOCATION);
+  AnonConst (const AnonConst &other);
+  AnonConst operator= (const AnonConst &other);
+
+  std::string as_string () const override;
+
+  void accept_vis (HIRFullVisitor &vis) override;
+  void accept_vis (HIRExpressionVisitor &vis) override;
+
+  ExprType get_expression_type () const final override
+  {
+    return ExprType::AnonConst;
+  }
+
+  location_t get_locus () const override { return locus; }
+  Expr &get_inner_expr () { return *expr; }
+  const Expr &get_inner_expr () const { return *expr; }
+
+private:
+  location_t locus;
+  std::unique_ptr<Expr> expr;
+
+  AnonConst *clone_expr_with_block_impl () const override
+  {
+    return new AnonConst (*this);
+  }
+};
+
+class ConstBlock : public ExprWithBlock
+{
+public:
+  ConstBlock (Analysis::NodeMapping mappings, AnonConst &&expr,
+             location_t locus = UNKNOWN_LOCATION,
+             AST::AttrVec outer_attrs = {});
+  ConstBlock (const ConstBlock &other);
+  ConstBlock operator= (const ConstBlock &other);
+
+  void accept_vis (HIRFullVisitor &vis) override;
+  void accept_vis (HIRExpressionVisitor &vis) override;
+
+  std::string as_string () const override;
+
+  ExprType get_expression_type () const final override
+  {
+    return ExprType::ConstBlock;
+  }
+
+  location_t get_locus () const override { return locus; }
+  AnonConst &get_const_expr () { return expr; }
+  const AnonConst &get_const_expr () const { return expr; }
+
+private:
+  AnonConst expr;
+  location_t locus;
+
+  ConstBlock *clone_expr_with_block_impl () const override
+  {
+    return new ConstBlock (*this);
+  }
+};
+
 // HIR node representing continue expression within loops
 class ContinueExpr : public ExprWithoutBlock
 {
@@ -2892,18 +2959,6 @@ class InlineAsmRegClass
   std::string placeholder;
 };
 
-struct AnonConst
-{
-  NodeId id;
-  std::unique_ptr<Expr> expr;
-
-  AnonConst (NodeId id, std::unique_ptr<Expr> expr);
-
-  AnonConst (const AnonConst &other);
-
-  AnonConst operator= (const AnonConst &other);
-};
-
 class InlineAsmOperand
 {
 public:
diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h 
b/gcc/rust/hir/tree/rust-hir-full-decls.h
index a1722b068218..ac88deea9346 100644
--- a/gcc/rust/hir/tree/rust-hir-full-decls.h
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -95,6 +95,8 @@ class FieldAccessExpr;
 struct ClosureParam;
 class ClosureExpr;
 class BlockExpr;
+class AnonConst;
+class ConstBlock;
 class ContinueExpr;
 class BreakExpr;
 class RangeExpr;
@@ -123,7 +125,6 @@ class AwaitExpr;
 class AsyncBlockExpr;
 class InlineAsmReg;
 class InlineAsmRegClass;
-struct AnonConst;
 class InlineAsmOperand;
 class InlineAsm;
 class LlvmInlineAsm;
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h 
b/gcc/rust/hir/tree/rust-hir-visitor.h
index c9344846798e..d3c209ec6612 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -64,6 +64,8 @@ public:
   virtual void visit (MethodCallExpr &expr) = 0;
   virtual void visit (FieldAccessExpr &expr) = 0;
   virtual void visit (BlockExpr &expr) = 0;
+  virtual void visit (AnonConst &expr) = 0;
+  virtual void visit (ConstBlock &expr) = 0;
   virtual void visit (ClosureExpr &expr) = 0;
   virtual void visit (ContinueExpr &expr) = 0;
   virtual void visit (BreakExpr &expr) = 0;
@@ -201,6 +203,8 @@ public:
   virtual void visit (FieldAccessExpr &) override {}
   virtual void visit (ClosureExpr &) override {}
   virtual void visit (BlockExpr &) override {}
+  virtual void visit (AnonConst &) override {}
+  virtual void visit (ConstBlock &) override {}
   virtual void visit (ContinueExpr &) override {}
   virtual void visit (BreakExpr &) override {}
   virtual void visit (RangeFromToExpr &) override {}
@@ -427,6 +431,8 @@ public:
   virtual void visit (MethodCallExpr &expr) = 0;
   virtual void visit (FieldAccessExpr &expr) = 0;
   virtual void visit (BlockExpr &expr) = 0;
+  virtual void visit (AnonConst &expr) = 0;
+  virtual void visit (ConstBlock &expr) = 0;
   virtual void visit (ContinueExpr &expr) = 0;
   virtual void visit (BreakExpr &expr) = 0;
   virtual void visit (RangeFromToExpr &expr) = 0;
diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index c94335734de0..ec45a8da6659 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -1047,6 +1047,33 @@ BlockExpr::as_string () const
   return str;
 }
 
+std::string
+AnonConst::as_string () const
+{
+  std::string istr = indent_spaces (enter);
+  std::string str = istr + "AnonConst:\n" + istr;
+
+  str += get_inner_expr ().as_string ();
+
+  str += "\n" + indent_spaces (out);
+
+  return str;
+}
+
+std::string
+ConstBlock::as_string () const
+{
+  std::string istr = indent_spaces (enter);
+
+  std::string str = istr + "ConstBlock:\n" + istr;
+
+  str += get_const_expr ().as_string ();
+
+  str += "\n" + indent_spaces (out);
+
+  return str;
+}
+
 std::string
 TypeAlias::as_string () const
 {
@@ -4054,6 +4081,18 @@ BlockExpr::accept_vis (HIRFullVisitor &vis)
   vis.visit (*this);
 }
 
+void
+AnonConst::accept_vis (HIRFullVisitor &vis)
+{
+  vis.visit (*this);
+}
+
+void
+ConstBlock::accept_vis (HIRFullVisitor &vis)
+{
+  vis.visit (*this);
+}
+
 void
 ContinueExpr::accept_vis (HIRFullVisitor &vis)
 {
@@ -5026,6 +5065,18 @@ BlockExpr::accept_vis (HIRExpressionVisitor &vis)
   vis.visit (*this);
 }
 
+void
+AnonConst::accept_vis (HIRExpressionVisitor &vis)
+{
+  vis.visit (*this);
+}
+
+void
+ConstBlock::accept_vis (HIRExpressionVisitor &vis)
+{
+  vis.visit (*this);
+}
+
 void
 Function::accept_vis (HIRStmtVisitor &vis)
 {
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 7c65e6638693..72659860e5be 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -642,6 +642,18 @@ TypeCheckExpr::visit (HIR::BlockExpr &expr)
     }
 }
 
+void
+TypeCheckExpr::visit (HIR::AnonConst &expr)
+{
+  infered = TypeCheckExpr::Resolve (expr.get_inner_expr ());
+}
+
+void
+TypeCheckExpr::visit (HIR::ConstBlock &expr)
+{
+  infered = TypeCheckExpr::Resolve (expr.get_const_expr ());
+}
+
 void
 TypeCheckExpr::visit (HIR::RangeFromToExpr &expr)
 {
@@ -813,7 +825,7 @@ typecheck_inline_asm_operand (HIR::InlineAsm &expr)
          }
          case RegisterType::Const: {
            auto anon_const = operand.get_const ().anon_const;
-           TypeCheckExpr::Resolve (*anon_const.expr);
+           TypeCheckExpr::Resolve (anon_const.get_inner_expr ());
            break;
          }
          case RegisterType::Sym: {
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h 
b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index 0b859f76f615..6ee383bd6e27 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -46,6 +46,8 @@ public:
   void visit (HIR::IfExpr &expr) override;
   void visit (HIR::IfExprConseqElse &expr) override;
   void visit (HIR::BlockExpr &expr) override;
+  void visit (HIR::AnonConst &expr) override;
+  void visit (HIR::ConstBlock &expr) override;
   void visit (HIR::UnsafeBlockExpr &expr) override;
   void visit (HIR::ArrayIndexExpr &expr) override;
   void visit (HIR::ArrayExpr &expr) override;

Reply via email to