]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gccrs: desugar: Add for-loop desugar to ExpressionYeast
authorArthur Cohen <arthur.cohen@embecosm.com>
Tue, 22 Jul 2025 13:00:32 +0000 (15:00 +0200)
committerArthur Cohen <arthur.cohen@embecosm.com>
Tue, 5 Aug 2025 14:36:59 +0000 (16:36 +0200)
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.

gcc/rust/ast/rust-desugar-for-loops.cc
gcc/rust/ast/rust-desugar-for-loops.h
gcc/rust/ast/rust-expression-yeast.cc
gcc/rust/ast/rust-expression-yeast.h
gcc/rust/rust-session-manager.cc

index ffc3470b656edb1a550430f02f8d95df03207877..496e8efb557ff3d9e2b26efedd9d6dd52d2b8064 100644 (file)
@@ -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
index 7beb69224968b390a524a9f036363cb68e06ef1c..3a8365cebbb413d278bad713d088f35493086653 100644 (file)
@@ -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
index 6c0b3d3cced3e84aa87d1db8f9ae263a8cb08256..e8cf6d5af8e49697fdf696c6ff2e9a3d98c1761e 100644 (file)
 #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
index 18712b46aaa05ffdd5f4b0a8bd7cc7d6b8b32e0c..855918fbc216e283746f8ca4897779a4118fb9c1 100644 (file)
@@ -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;
index dc59be0741678a82cc876699be11a16e6b6545ef..17f9c06040d0370110c291a8109d3e014b9afbf8 100644 (file)
@@ -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