From: Arthur Cohen <arthur.co...@embecosm.com>

gcc/rust/ChangeLog:

        * hir/tree/rust-hir-stmt.h (class LetStmt): Add optional diverging else 
expression.
        * hir/tree/rust-hir-stmt.cc: Likewise.
        * hir/rust-ast-lower-stmt.cc (ASTLoweringStmt::visit): Add handling for 
lowering
        diverging else.
---
 gcc/rust/hir/rust-ast-lower-stmt.cc | 14 ++++++++++----
 gcc/rust/hir/tree/rust-hir-stmt.cc  | 12 +++++++++++-
 gcc/rust/hir/tree/rust-hir-stmt.h   | 16 ++++++++++++++++
 3 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/gcc/rust/hir/rust-ast-lower-stmt.cc 
b/gcc/rust/hir/rust-ast-lower-stmt.cc
index fd2cdfb0f11..dbb1723dfc5 100644
--- a/gcc/rust/hir/rust-ast-lower-stmt.cc
+++ b/gcc/rust/hir/rust-ast-lower-stmt.cc
@@ -76,20 +76,26 @@ ASTLoweringStmt::visit (AST::LetStmt &stmt)
     type
       = std::unique_ptr<Type> (ASTLoweringType::translate (stmt.get_type ()));
 
-  tl::optional<std::unique_ptr<HIR::Expr>> init_expression = tl::nullopt;
+  tl::optional<std::unique_ptr<HIR::Expr>> init_expr = tl::nullopt;
+  tl::optional<std::unique_ptr<HIR::Expr>> else_expr = tl::nullopt;
 
   if (stmt.has_init_expr ())
-    init_expression = std::unique_ptr<HIR::Expr> (
+    init_expr = std::unique_ptr<HIR::Expr> (
       ASTLoweringExpr::translate (stmt.get_init_expr ()));
 
+  if (stmt.has_else_expr ())
+    else_expr = std::unique_ptr<HIR::Expr> (
+      ASTLoweringExpr::translate (stmt.get_else_expr ()));
+
   auto crate_num = mappings.get_current_crate ();
   Analysis::NodeMapping mapping (crate_num, stmt.get_node_id (),
                                 mappings.get_next_hir_id (crate_num),
                                 UNKNOWN_LOCAL_DEFID);
   translated
     = new HIR::LetStmt (mapping, std::unique_ptr<HIR::Pattern> (variables),
-                       std::move (init_expression), std::move (type),
-                       stmt.get_outer_attrs (), stmt.get_locus ());
+                       std::move (init_expr), std::move (else_expr),
+                       std::move (type), stmt.get_outer_attrs (),
+                       stmt.get_locus ());
 }
 
 void
diff --git a/gcc/rust/hir/tree/rust-hir-stmt.cc 
b/gcc/rust/hir/tree/rust-hir-stmt.cc
index 025f67e2c9b..fd58e29c7f8 100644
--- a/gcc/rust/hir/tree/rust-hir-stmt.cc
+++ b/gcc/rust/hir/tree/rust-hir-stmt.cc
@@ -26,11 +26,13 @@ namespace HIR {
 LetStmt::LetStmt (Analysis::NodeMapping mappings,
                  std::unique_ptr<Pattern> variables_pattern,
                  tl::optional<std::unique_ptr<Expr>> init_expr,
+                 tl::optional<std::unique_ptr<Expr>> else_expr,
                  tl::optional<std::unique_ptr<Type>> type,
                  AST::AttrVec outer_attrs, location_t locus)
   : Stmt (std::move (mappings)), outer_attrs (std::move (outer_attrs)),
     variables_pattern (std::move (variables_pattern)), type (std::move (type)),
-    init_expr (std::move (init_expr)), locus (locus)
+    init_expr (std::move (init_expr)), else_expr (std::move (else_expr)),
+    locus (locus)
 {}
 
 LetStmt::LetStmt (LetStmt const &other)
@@ -43,6 +45,8 @@ LetStmt::LetStmt (LetStmt const &other)
   // guard to prevent null dereference (always required)
   if (other.has_init_expr ())
     init_expr = other.get_init_expr ().clone_expr ();
+  if (other.has_else_expr ())
+    else_expr = other.get_else_expr ().clone_expr ();
 
   if (other.has_type ())
     type = other.get_type ().clone_type ();
@@ -67,6 +71,12 @@ LetStmt::operator= (LetStmt const &other)
     init_expr = other.get_init_expr ().clone_expr ();
   else
     init_expr = nullptr;
+
+  if (other.has_else_expr ())
+    else_expr = other.get_else_expr ().clone_expr ();
+  else
+    else_expr = tl::nullopt;
+
   if (other.has_type ())
     type = other.get_type ().clone_type ();
   else
diff --git a/gcc/rust/hir/tree/rust-hir-stmt.h 
b/gcc/rust/hir/tree/rust-hir-stmt.h
index 3db1728202e..9c1a9eccc38 100644
--- a/gcc/rust/hir/tree/rust-hir-stmt.h
+++ b/gcc/rust/hir/tree/rust-hir-stmt.h
@@ -101,6 +101,7 @@ class LetStmt : public Stmt
   tl::optional<std::unique_ptr<Type>> type;
 
   tl::optional<std::unique_ptr<Expr>> init_expr;
+  tl::optional<std::unique_ptr<Expr>> else_expr;
 
   location_t locus;
 
@@ -113,12 +114,15 @@ public:
 
   // Returns whether let statement has an initialisation expression.
   bool has_init_expr () const { return init_expr.has_value (); }
+  // Returns whether let statement has a diverging else expression.
+  bool has_else_expr () const { return else_expr.has_value (); }
 
   std::string as_string () const override;
 
   LetStmt (Analysis::NodeMapping mappings,
           std::unique_ptr<Pattern> variables_pattern,
           tl::optional<std::unique_ptr<Expr>> init_expr,
+          tl::optional<std::unique_ptr<Expr>> else_expr,
           tl::optional<std::unique_ptr<Type>> type, AST::AttrVec outer_attrs,
           location_t locus);
 
@@ -167,6 +171,18 @@ public:
     return *init_expr.value ();
   }
 
+  HIR::Expr &get_else_expr ()
+  {
+    rust_assert (*else_expr);
+    return *else_expr.value ();
+  }
+
+  const HIR::Expr &get_else_expr () const
+  {
+    rust_assert (*else_expr);
+    return *else_expr.value ();
+  }
+
   HIR::Pattern &get_pattern () { return *variables_pattern; }
 
   bool is_item () const override final { return false; }
-- 
2.49.0

Reply via email to