rust/rust-expand-format-args.o \
rust/rust-lang-item.o \
rust/rust-collect-lang-items.o \
+ rust/rust-expression-yeast.o \
rust/rust-desugar-for-loops.o \
rust/rust-desugar-question-mark.o \
rust/rust-desugar-apit.o \
+ # rust/rust-desugar-try-block.o \
$(END)
# removed object files from here
DesugarQuestionMark::DesugarQuestionMark () {}
void
-DesugarQuestionMark::go (AST::Crate &crate)
+DesugarQuestionMark::go (std::unique_ptr<Expr> &ptr)
{
- DesugarQuestionMark::visit (crate);
-}
-
-void
-DesugarQuestionMark::visit (ExprStmt &stmt)
-{
- if (stmt.get_expr ().get_expr_kind () == Expr::Kind::ErrorPropagation)
- desugar_and_replace (stmt.get_expr_ptr ());
-
- DefaultASTVisitor::visit (stmt);
-}
-
-void
-DesugarQuestionMark::visit (CallExpr &call)
-{
- if (call.get_function_expr ().get_expr_kind ()
- == Expr::Kind::ErrorPropagation)
- desugar_and_replace (call.get_function_expr_ptr ());
-
- for (auto &arg : call.get_params ())
- if (arg->get_expr_kind () == Expr::Kind::ErrorPropagation)
- desugar_and_replace (arg);
-
- DefaultASTVisitor::visit (call);
-}
-
-void
-DesugarQuestionMark::visit (LetStmt &stmt)
-{
- if (stmt.has_init_expr ()
- && stmt.get_init_expr ().get_expr_kind () == Expr::Kind::ErrorPropagation)
- desugar_and_replace (stmt.get_init_expr_ptr ());
+ auto original = static_cast<ErrorPropagationExpr &> (*ptr);
+ auto desugared = DesugarQuestionMark ().desugar (original);
- DefaultASTVisitor::visit (stmt);
+ ptr = std::move (desugared);
}
MatchArm
MatchCase
err_case (Builder &builder)
{
+ // TODO: We need to handle the case where there is an enclosing `try {}`
+ // block, as that will create an additional block label that we can break to.
+ // This allows try blocks to use the question mark operator without having the
+ // offending statement early return from the enclosing function
+ // FIXME: How to mark that there is an enclosing block label?
+
auto val = builder.identifier_pattern ("err");
auto patterns = std::vector<std::unique_ptr<Pattern>> ();
expr.get_locus ()));
}
-void
-DesugarQuestionMark::desugar_and_replace (std::unique_ptr<Expr> &ptr)
-{
- auto original = static_cast<ErrorPropagationExpr &> (*ptr);
- auto desugared = desugar (original);
-
- ptr = std::move (desugared);
-}
-
} // namespace AST
} // namespace Rust
#ifndef RUST_DESUGAR_QUESTION_MARK
#define RUST_DESUGAR_QUESTION_MARK
-#include "rust-ast-visitor.h"
#include "rust-expr.h"
-#include "rust-stmt.h"
namespace Rust {
namespace AST {
// }
// }
// ```
-class DesugarQuestionMark : public DefaultASTVisitor
+class DesugarQuestionMark
{
- using DefaultASTVisitor::visit;
-
public:
- DesugarQuestionMark ();
- void go (AST::Crate &);
+ static void go (std::unique_ptr<Expr> &ptr);
private:
- void desugar_and_replace (std::unique_ptr<Expr> &ptr);
- std::unique_ptr<Expr> desugar (ErrorPropagationExpr &);
+ DesugarQuestionMark ();
- void visit (AST::ExprStmt &) override;
- void visit (AST::CallExpr &) override;
- void visit (AST::LetStmt &) override;
+ std::unique_ptr<Expr> desugar (ErrorPropagationExpr &);
};
} // namespace AST
--- /dev/null
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-expression-yeast.h"
+#include "rust-ast-visitor.h"
+#include "rust-desugar-question-mark.h"
+#include "rust-ast-full.h"
+
+namespace Rust {
+namespace AST {
+
+void
+ExpressionYeast::go (AST::Crate &crate)
+{
+ DefaultASTVisitor::visit (crate);
+}
+
+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;
+
+ default:
+ break;
+ }
+}
+
+void
+ExpressionYeast::visit (ExprStmt &stmt)
+{
+ dispatch (stmt.get_expr_ptr ());
+
+ DefaultASTVisitor::visit (stmt);
+}
+
+void
+ExpressionYeast::visit (CallExpr &call)
+{
+ dispatch (call.get_function_expr_ptr ());
+
+ for (auto &arg : call.get_params ())
+ dispatch (arg);
+
+ DefaultASTVisitor::visit (call);
+}
+
+void
+ExpressionYeast::visit (BlockExpr &block)
+{
+ for (auto &stmt : block.get_statements ())
+ DefaultASTVisitor::visit (stmt);
+
+ if (block.has_tail_expr ())
+ dispatch (block.get_tail_expr_ptr ());
+}
+
+void
+ExpressionYeast::visit (LetStmt &stmt)
+{
+ if (stmt.has_init_expr ())
+ dispatch (stmt.get_init_expr_ptr ());
+
+ DefaultASTVisitor::visit (stmt);
+}
+
+} // namespace AST
+} // namespace Rust
--- /dev/null
+// Copyright (C) 2025 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#ifndef RUST_EXPRESSION_YEAST
+#define RUST_EXPRESSION_YEAST
+
+#include "rust-ast-visitor.h"
+#include "rust-ast.h"
+#include "rust-desugar-question-mark.h"
+
+namespace Rust {
+namespace AST {
+
+// This visitor takes care of all the expression desugars: try-blocks,
+// error-propagation, etc.
+class ExpressionYeast : public AST::DefaultASTVisitor
+{
+ using AST::DefaultASTVisitor::visit;
+
+public:
+ void go (AST::Crate &);
+
+private:
+ // Dispatch to the proper desugar
+ void dispatch (std::unique_ptr<Expr> &expr);
+
+ void visit (AST::ExprStmt &) override;
+ void visit (AST::CallExpr &) override;
+ void visit (AST::LetStmt &) override;
+ void visit (AST::BlockExpr &) override;
+};
+
+} // namespace AST
+} // namespace Rust
+
+#endif // ! RUST_EXPRESSION_YEAST
#include "rust-desugar-question-mark.h"
#include "rust-desugar-apit.h"
#include "rust-diagnostics.h"
+#include "rust-expression-yeast.h"
#include "rust-hir-pattern-analysis.h"
#include "rust-immutable-name-resolution-context.h"
#include "rust-unsafe-checker.h"
// handle AST desugaring
if (!saw_errors ())
{
+ AST::ExpressionYeast ().go (crate);
+
AST::DesugarForLoops ().go (crate);
- AST::DesugarQuestionMark ().go (crate);
AST::DesugarApit ().go (crate);
// HACK: we may need a final TopLevel pass