aboutsummaryrefslogtreecommitdiff
path: root/gcc/rust/hir/rust-ast-lower.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/rust/hir/rust-ast-lower.cc')
-rw-r--r--gcc/rust/hir/rust-ast-lower.cc185
1 files changed, 132 insertions, 53 deletions
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index 5a5c93f..ebdf981 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -24,6 +24,8 @@
#include "rust-ast-lower-type.h"
#include "rust-ast-lower-pattern.h"
#include "rust-ast-lower-struct-field-expr.h"
+#include "rust-expr.h"
+#include "rust-hir-expr.h"
namespace Rust {
namespace HIR {
@@ -102,7 +104,11 @@ ASTLoweringBlock::visit (AST::BlockExpr &expr)
for (auto &s : expr.get_statements ())
{
- if (s->get_ast_kind () == AST::Kind::MACRO_INVOCATION)
+ // FIXME: We basically need to do that check for *every* single node in
+ // the AST. this isn't realistic and this should be turned into an
+ // optional, debug-visitor instead, which goes through the entire AST and
+ // checks if any of the nodes are macro invocations
+ if (s->get_stmt_kind () == AST::Stmt::Kind::MacroInvocation)
rust_fatal_error (
s->get_locus (),
"macro invocations should not get lowered to HIR - At "
@@ -198,62 +204,144 @@ ASTLoweringIfBlock::visit (AST::IfExprConseqElse &expr)
std::unique_ptr<HIR::ExprWithBlock> (else_block), expr.get_locus ());
}
+/**
+ * Lowers the common part "if let 'pattern' = 'expr' { 'if_block' }" of
+ * IfLetExpr[ConseqElse]:
+ * - 'expr' is lowered into *BRANCH_VALUE
+ * - 'pattern' + 'if_block' are lowered and resulting ARM pushed in MATCH_ARMS
+ * - 'KASE_ELSE_EXPR' is the lowered HIR to be used in the else part.
+ *
+ * Looks like:
+ *
+ * match (expr) {
+ * pattern => {if_block}
+ * _ => kase_else_expr
+ * }
+ *
+ */
void
-ASTLoweringIfLetBlock::visit (AST::IfLetExpr &expr)
+ASTLoweringIfLetBlock::desugar_iflet (AST::IfLetExpr &expr,
+ HIR::Expr **branch_value,
+ HIR::Expr *kase_else_expr,
+ std::vector<HIR::MatchCase> &match_arms)
{
- std::vector<std::unique_ptr<HIR::Pattern>> patterns;
+ HIR::Expr *kase_expr;
+ std::vector<std::unique_ptr<HIR::Pattern>> match_arm_patterns;
+
+ *branch_value = ASTLoweringExpr::translate (expr.get_value_expr ());
+ kase_expr = ASTLoweringExpr::translate (expr.get_if_block ());
+
+ // (stable) if let only accepts a single pattern, but (unstable) if let chains
+ // need more than one pattern.
+ // We don't support if let chains, so only support a single pattern.
+ rust_assert (expr.get_patterns ().size () == 1);
+
for (auto &pattern : expr.get_patterns ())
{
HIR::Pattern *ptrn = ASTLoweringPattern::translate (*pattern);
- patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn));
+ match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn));
}
- HIR::Expr *value_ptr = ASTLoweringExpr::translate (expr.get_value_expr ());
- bool ignored_terminated = false;
- HIR::BlockExpr *block
- = ASTLoweringBlock::translate (expr.get_if_block (), &ignored_terminated);
+ // The match arm corresponding to the if let pattern when it matches.
+ HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (), nullptr,
+ {});
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- translated = new HIR::IfLetExpr (mapping, std::move (patterns),
- std::unique_ptr<HIR::Expr> (value_ptr),
- std::unique_ptr<HIR::BlockExpr> (block),
- expr.get_locus ());
+ HIR::MatchCase kase (std::move (mapping), std::move (arm),
+ std::unique_ptr<HIR::Expr> (kase_expr));
+ match_arms.push_back (std::move (kase));
+
+ // The default match arm when the if let pattern does not match
+ std::vector<std::unique_ptr<HIR::Pattern>> match_arm_patterns_wildcard;
+ Analysis::NodeMapping mapping_default (crate_num, expr.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ std::unique_ptr<HIR::WildcardPattern> wc
+ = std::unique_ptr<HIR::WildcardPattern> (
+ new HIR::WildcardPattern (mapping_default, expr.get_locus ()));
+
+ match_arm_patterns_wildcard.push_back (std::move (wc));
+
+ HIR::MatchArm arm_default (std::move (match_arm_patterns_wildcard),
+ expr.get_locus (), nullptr, {});
+
+ HIR::MatchCase kase_else (std::move (mapping_default),
+ std::move (arm_default),
+ std::unique_ptr<HIR::Expr> (kase_else_expr));
+ match_arms.push_back (std::move (kase_else));
}
void
-ASTLoweringIfLetBlock::visit (AST::IfLetExprConseqElse &expr)
+ASTLoweringIfLetBlock::visit (AST::IfLetExpr &expr)
{
- std::vector<std::unique_ptr<HIR::Pattern>> patterns;
- for (auto &pattern : expr.get_patterns ())
- {
- HIR::Pattern *ptrn = ASTLoweringPattern::translate (*pattern);
- patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn));
- }
- HIR::Expr *value_ptr = ASTLoweringExpr::translate (expr.get_value_expr ());
+ // Desugar:
+ // if let Some(y) = some_value {
+ // bar();
+ // }
+ //
+ // into:
+ //
+ // match some_value {
+ // Some(y) => {bar();},
+ // _ => ()
+ // }
+
+ HIR::Expr *branch_value;
- bool ignored_terminated = false;
- HIR::BlockExpr *block
- = ASTLoweringBlock::translate (expr.get_if_block (), &ignored_terminated);
+ std::vector<HIR::MatchCase> match_arms;
+ auto crate_num = mappings.get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
- HIR::ExprWithBlock *else_block
- = ASTLoweringExprWithBlock::translate (expr.get_else_block (),
- &ignored_terminated);
+ HIR::TupleExpr *unit
+ = new HIR::TupleExpr (mapping, {}, {}, {}, expr.get_locus ());
+
+ desugar_iflet (expr, &branch_value, unit, match_arms);
+
+ translated
+ = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value),
+ std::move (match_arms), {}, {}, expr.get_locus ());
+}
+
+void
+ASTLoweringIfLetBlock::visit (AST::IfLetExprConseqElse &expr)
+{
+ // desugar:
+ // if let Some(y) = some_value {
+ // bar();
+ // } else {
+ // baz();
+ // }
+ //
+ // into
+ // match some_value {
+ // Some(y) => {bar();},
+ // _ => {baz();}
+ // }
+ //
+
+ HIR::Expr *branch_value;
+ std::vector<HIR::MatchCase> match_arms;
- rust_assert (else_block);
+ HIR::Expr *kase_else_expr
+ = ASTLoweringExpr::translate (expr.get_else_block ());
+
+ desugar_iflet (expr, &branch_value, kase_else_expr, match_arms);
auto crate_num = mappings.get_current_crate ();
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
mappings.get_next_hir_id (crate_num),
UNKNOWN_LOCAL_DEFID);
- translated = new HIR::IfLetExprConseqElse (
- mapping, std::move (patterns), std::unique_ptr<HIR::Expr> (value_ptr),
- std::unique_ptr<HIR::BlockExpr> (block),
- std::unique_ptr<HIR::ExprWithBlock> (else_block), expr.get_locus ());
+ translated
+ = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value),
+ std::move (match_arms), {}, {}, expr.get_locus ());
}
// rust-ast-lower-struct-field-expr.h
@@ -330,24 +418,7 @@ ASTLoweringExprWithBlock::visit (AST::WhileLoopExpr &expr)
void
ASTLoweringExprWithBlock::visit (AST::ForLoopExpr &expr)
{
- // TODO FIXME
-
- // HIR::BlockExpr *loop_block
- // = ASTLoweringBlock::translate (expr.get_loop_block ().get (),
- // &terminated);
- // HIR::LoopLabel loop_label = lower_loop_label (expr.get_loop_label ());
- // HIR::Expr *iterator_expr
- // = ASTLoweringExpr::translate (expr.get_iterator_expr ().get (),
- // &terminated);
- // HIR::Pattern *loop_pattern
- // = ASTLoweringPattern::translate (expr.get_pattern ().get ());
-
- // auto crate_num = mappings->get_current_crate ();
- // Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
- // mappings->get_next_hir_id (crate_num),
- // UNKNOWN_LOCAL_DEFID);
-
- gcc_unreachable ();
+ rust_unreachable ();
}
void
@@ -406,6 +477,18 @@ ASTLoweringExprWithBlock::visit (AST::MatchExpr &expr)
void
ASTLowerPathInExpression::visit (AST::PathInExpression &expr)
{
+ auto crate_num = mappings.get_current_crate ();
+ Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+ mappings.get_next_hir_id (crate_num),
+ UNKNOWN_LOCAL_DEFID);
+
+ if (expr.is_lang_item ())
+ {
+ translated = new HIR::PathInExpression (mapping, expr.get_lang_item (),
+ expr.get_locus (), false);
+ return;
+ }
+
std::vector<HIR::PathExprSegment> path_segments;
auto &segments = expr.get_segments ();
for (auto &s : segments)
@@ -416,10 +499,6 @@ ASTLowerPathInExpression::visit (AST::PathInExpression &expr)
HIR::PathExprSegment *lowered_seg = &path_segments.back ();
mappings.insert_hir_path_expr_seg (lowered_seg);
}
- auto crate_num = mappings.get_current_crate ();
- Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
- mappings.get_next_hir_id (crate_num),
- UNKNOWN_LOCAL_DEFID);
translated = new HIR::PathInExpression (mapping, std::move (path_segments),
expr.get_locus (),