https://gcc.gnu.org/g:40754a08e5bf529cb57223105b16e608f3d9f030

commit r16-2973-g40754a08e5bf529cb57223105b16e608f3d9f030
Author: Arthur Cohen <arthur.co...@embecosm.com>
Date:   Tue Jul 22 15:00:32 2025 +0200

    gccrs: desugar: Add for-loop desugar to ExpressionYeast
    
    gcc/rust/ChangeLog:
    
            * ast/rust-desugar-for-loops.h: Adapt API and remove visitor.
            * ast/rust-desugar-for-loops.cc: Likewise.
            * ast/rust-expression-yeast.cc: Call DesugarForLoop.
            * ast/rust-expression-yeast.h: Declare dispatch_loops function.
            * rust-session-manager.cc (Session::expansion): Do not call 
for-loop desugar.

Diff:
---
 gcc/rust/ast/rust-desugar-for-loops.cc | 46 ++++++----------------------------
 gcc/rust/ast/rust-desugar-for-loops.h  | 15 ++++-------
 gcc/rust/ast/rust-expression-yeast.cc  | 29 +++++++++++++++++++--
 gcc/rust/ast/rust-expression-yeast.h   |  1 +
 gcc/rust/rust-session-manager.cc       |  1 -
 5 files changed, 41 insertions(+), 51 deletions(-)

diff --git a/gcc/rust/ast/rust-desugar-for-loops.cc 
b/gcc/rust/ast/rust-desugar-for-loops.cc
index ffc3470b656e..496e8efb557f 100644
--- a/gcc/rust/ast/rust-desugar-for-loops.cc
+++ b/gcc/rust/ast/rust-desugar-for-loops.cc
@@ -17,7 +17,6 @@
 // <http://www.gnu.org/licenses/>.
 
 #include "rust-desugar-for-loops.h"
-#include "rust-ast-visitor.h"
 #include "rust-ast.h"
 #include "rust-hir-map.h"
 #include "rust-path.h"
@@ -31,19 +30,6 @@ namespace AST {
 
 DesugarForLoops::DesugarForLoops () {}
 
-void
-DesugarForLoops::go (AST::Crate &crate)
-{
-  DefaultASTVisitor::visit (crate);
-}
-
-static void
-replace_for_loop (std::unique_ptr<Expr> &for_loop,
-                 std::unique_ptr<Expr> &&expanded)
-{
-  for_loop = std::move (expanded);
-}
-
 MatchArm
 DesugarForLoops::DesugarCtx::make_match_arm (std::unique_ptr<Pattern> &&path)
 {
@@ -98,7 +84,7 @@ DesugarForLoops::DesugarCtx::statementify 
(std::unique_ptr<Expr> &&expr)
 }
 
 std::unique_ptr<Expr>
-DesugarForLoops::desugar (AST::ForLoopExpr &expr)
+DesugarForLoops::desugar (ForLoopExpr &expr)
 {
   auto ctx = DesugarCtx (expr.get_locus ());
 
@@ -170,34 +156,18 @@ DesugarForLoops::desugar (AST::ForLoopExpr &expr)
 }
 
 void
-DesugarForLoops::maybe_desugar_expr (std::unique_ptr<Expr> &expr)
+DesugarForLoops::go (std::unique_ptr<Expr> &ptr)
 {
-  if (expr->get_expr_kind () == AST::Expr::Kind::Loop)
-    {
-      auto &loop = static_cast<AST::BaseLoopExpr &> (*expr);
-
-      if (loop.get_loop_kind () == AST::BaseLoopExpr::Kind::For)
-       {
-         auto &for_loop = static_cast<AST::ForLoopExpr &> (loop);
-
-         auto desugared = desugar (for_loop);
+  rust_assert (ptr->get_expr_kind () == Expr::Kind::Loop);
 
-         replace_for_loop (expr, std::move (desugared));
-       }
-    }
-}
+  auto &loop = static_cast<BaseLoopExpr &> (*ptr);
 
-void
-DesugarForLoops::visit (AST::BlockExpr &block)
-{
-  for (auto &stmt : block.get_statements ())
-    if (stmt->get_stmt_kind () == AST::Stmt::Kind::Expr)
-      maybe_desugar_expr (static_cast<AST::ExprStmt &> (*stmt).get_expr_ptr 
());
+  rust_assert (loop.get_loop_kind () == BaseLoopExpr::Kind::For);
 
-  if (block.has_tail_expr ())
-    maybe_desugar_expr (block.get_tail_expr_ptr ());
+  auto &for_loop = static_cast<ForLoopExpr &> (loop);
+  auto desugared = DesugarForLoops ().desugar (for_loop);
 
-  DefaultASTVisitor::visit (block);
+  ptr = std::move (desugared);
 }
 
 } // namespace AST
diff --git a/gcc/rust/ast/rust-desugar-for-loops.h 
b/gcc/rust/ast/rust-desugar-for-loops.h
index 7beb69224968..3a8365cebbb4 100644
--- a/gcc/rust/ast/rust-desugar-for-loops.h
+++ b/gcc/rust/ast/rust-desugar-for-loops.h
@@ -20,7 +20,6 @@
 #define RUST_DESUGAR_FOR_LOOPS_H
 
 #include "rust-ast-builder.h"
-#include "rust-ast-visitor.h"
 #include "rust-expr.h"
 
 namespace Rust {
@@ -69,15 +68,14 @@ namespace AST {
 // of the way the typechecker is currently structured, where it will fetch name
 // resolution information in order to typecheck paths - which technically isn't
 // necessary.
-class DesugarForLoops : public DefaultASTVisitor
+class DesugarForLoops
 {
-  using DefaultASTVisitor::visit;
-
 public:
-  DesugarForLoops ();
-  void go (AST::Crate &);
+  static void go (std::unique_ptr<Expr> &ptr);
 
 private:
+  DesugarForLoops ();
+
   struct DesugarCtx
   {
     DesugarCtx (location_t loc) : builder (Builder (loc)), loc (loc) {}
@@ -96,10 +94,7 @@ private:
     constexpr static const char *result_id = "#result";
   };
 
-  std::unique_ptr<Expr> desugar (AST::ForLoopExpr &expr);
-  void maybe_desugar_expr (std::unique_ptr<Expr> &expr);
-
-  void visit (AST::BlockExpr &) override;
+  std::unique_ptr<Expr> desugar (ForLoopExpr &expr);
 };
 
 } // namespace AST
diff --git a/gcc/rust/ast/rust-expression-yeast.cc 
b/gcc/rust/ast/rust-expression-yeast.cc
index 6c0b3d3cced3..e8cf6d5af8e4 100644
--- a/gcc/rust/ast/rust-expression-yeast.cc
+++ b/gcc/rust/ast/rust-expression-yeast.cc
@@ -20,7 +20,10 @@
 #include "rust-ast-visitor.h"
 #include "rust-desugar-question-mark.h"
 #include "rust-desugar-try-block.h"
+#include "rust-desugar-for-loops.h"
 #include "rust-ast-full.h"
+#include "rust-expr.h"
+#include "rust-stmt.h"
 
 namespace Rust {
 namespace AST {
@@ -31,18 +34,37 @@ ExpressionYeast::go (AST::Crate &crate)
   DefaultASTVisitor::visit (crate);
 }
 
+void
+ExpressionYeast::dispatch_loops (std::unique_ptr<Expr> &loop_expr)
+{
+  auto &loop = static_cast<BaseLoopExpr &> (*loop_expr.get ());
+
+  switch (loop.get_loop_kind ())
+    {
+    case BaseLoopExpr::Kind::For:
+      DesugarForLoops::go (loop_expr);
+      break;
+    case BaseLoopExpr::Kind::Loop:
+    case BaseLoopExpr::Kind::While:
+    case BaseLoopExpr::Kind::WhileLet:
+      break;
+    }
+}
+
 void
 ExpressionYeast::dispatch (std::unique_ptr<Expr> &expr)
 {
   switch (expr->get_expr_kind ())
     {
-      // TODO: Handle try-blocks
     case Expr::Kind::ErrorPropagation:
       DesugarQuestionMark::go (expr);
       break;
     case Expr::Kind::Try:
       DesugarTryBlock::go (expr);
       break;
+    case Expr::Kind::Loop:
+      dispatch_loops (expr);
+      break;
 
     default:
       break;
@@ -72,10 +94,13 @@ void
 ExpressionYeast::visit (BlockExpr &block)
 {
   for (auto &stmt : block.get_statements ())
-    DefaultASTVisitor::visit (stmt);
+    if (stmt->get_stmt_kind () == Stmt::Kind::Expr)
+      dispatch (static_cast<ExprStmt &> (*stmt).get_expr_ptr ());
 
   if (block.has_tail_expr ())
     dispatch (block.get_tail_expr_ptr ());
+
+  DefaultASTVisitor::visit (block);
 }
 
 void
diff --git a/gcc/rust/ast/rust-expression-yeast.h 
b/gcc/rust/ast/rust-expression-yeast.h
index 18712b46aaa0..855918fbc216 100644
--- a/gcc/rust/ast/rust-expression-yeast.h
+++ b/gcc/rust/ast/rust-expression-yeast.h
@@ -38,6 +38,7 @@ public:
 private:
   // Dispatch to the proper desugar
   void dispatch (std::unique_ptr<Expr> &expr);
+  void dispatch_loops (std::unique_ptr<Expr> &loop_expr);
 
   void visit (AST::ExprStmt &) override;
   void visit (AST::CallExpr &) override;
diff --git a/gcc/rust/rust-session-manager.cc b/gcc/rust/rust-session-manager.cc
index dc59be074167..17f9c06040d0 100644
--- a/gcc/rust/rust-session-manager.cc
+++ b/gcc/rust/rust-session-manager.cc
@@ -988,7 +988,6 @@ Session::expansion (AST::Crate &crate, 
Resolver2_0::NameResolutionContext &ctx)
     {
       AST::ExpressionYeast ().go (crate);
 
-      AST::DesugarForLoops ().go (crate);
       AST::DesugarApit ().go (crate);
 
       // HACK: we may need a final TopLevel pass

Reply via email to