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