From: Pierre-Emmanuel Patry <[email protected]>

gcc/rust/ChangeLog:

        * parse/rust-parse-error.h (struct BlockExpr): Add BlockExpr error type
        * parse/rust-parse-impl-expr.hxx: Update return types.
        * parse/rust-parse-impl.hxx: Likewise.
        * parse/rust-parse.h: Update function prototypes.

Signed-off-by: Pierre-Emmanuel Patry <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/00efe951e482ccd426c6767a7240553ce6288e39

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4330

 gcc/rust/parse/rust-parse-error.h       |  17 +++
 gcc/rust/parse/rust-parse-impl-expr.hxx | 140 +++++++++++++-----------
 gcc/rust/parse/rust-parse-impl.hxx      |  24 ++--
 gcc/rust/parse/rust-parse.h             |   2 +-
 4 files changed, 111 insertions(+), 72 deletions(-)

diff --git a/gcc/rust/parse/rust-parse-error.h 
b/gcc/rust/parse/rust-parse-error.h
index 06497a770..c5a52becd 100644
--- a/gcc/rust/parse/rust-parse-error.h
+++ b/gcc/rust/parse/rust-parse-error.h
@@ -385,6 +385,23 @@ private:
   Self (Kind kind) : kind (kind) {}
 };
 
+struct BlockExpr
+{
+  static tl::expected<std::unique_ptr<AST::BlockExpr>, BlockExpr>
+  make_malformed ()
+  {
+    return tl::unexpected<BlockExpr> (BlockExpr (Kind::MALFORMED));
+  }
+
+  enum class Kind
+  {
+    MALFORMED,
+  } kind;
+
+private:
+  BlockExpr (Kind kind) : kind (kind) {}
+};
+
 } // namespace Error
 } // namespace Parse
 } // namespace Rust
diff --git a/gcc/rust/parse/rust-parse-impl-expr.hxx 
b/gcc/rust/parse/rust-parse-impl-expr.hxx
index 958b303ab..99fb3cfa0 100644
--- a/gcc/rust/parse/rust-parse-impl-expr.hxx
+++ b/gcc/rust/parse/rust-parse-impl-expr.hxx
@@ -26,7 +26,7 @@ namespace Rust {
 
 // Parses a block expression, including the curly braces at start and end.
 template <typename ManagedTokenSource>
-std::unique_ptr<AST::BlockExpr>
+tl::expected<std::unique_ptr<AST::BlockExpr>, Parse::Error::BlockExpr>
 Parser<ManagedTokenSource>::parse_block_expr (
   AST::AttrVec outer_attrs, tl::optional<AST::LoopLabel> label,
   location_t pratt_parsed_loc)
@@ -38,7 +38,7 @@ Parser<ManagedTokenSource>::parse_block_expr (
       if (!skip_token (LEFT_CURLY))
        {
          skip_after_end_block ();
-         return nullptr;
+         return Parse::Error::BlockExpr::make_malformed ();
        }
     }
 
@@ -55,7 +55,7 @@ Parser<ManagedTokenSource>::parse_block_expr (
       if (expr_or_stmt.is_error ())
        {
          skip_after_end_block ();
-         return nullptr;
+         return Parse::Error::BlockExpr::make_malformed ();
        }
 
       t = lexer.peek_token ();
@@ -82,7 +82,7 @@ Parser<ManagedTokenSource>::parse_block_expr (
       add_error (std::move (error));
 
       skip_after_end_block ();
-      return nullptr;
+      return Parse::Error::BlockExpr::make_malformed ();
     }
 
   // grammar allows for empty block expressions
@@ -123,15 +123,16 @@ std::unique_ptr<AST::ConstBlock>
 Parser<ManagedTokenSource>::parse_const_block_expr (AST::AttrVec outer_attrs,
                                                    location_t locus)
 {
-  auto block = parse_block_expr ();
+  auto block_res = parse_block_expr ();
 
-  if (!block)
+  if (!block_res)
     {
       add_error (Error (locus, "failed to parse inner block in const block"));
       skip_after_end_block ();
 
       return nullptr;
     }
+  auto block = std::move (block_res.value ());
 
   auto block_locus = block->get_locus ();
 
@@ -258,8 +259,8 @@ Parser<ManagedTokenSource>::parse_closure_expr 
(AST::AttrVec outer_attrs)
        }
 
       // parse block expr, which is required
-      std::unique_ptr<AST::BlockExpr> block = parse_block_expr ();
-      if (block == nullptr)
+      auto block = parse_block_expr ();
+      if (!block)
        {
          // error
          Error error (lexer.peek_token ()->get_locus (),
@@ -271,7 +272,8 @@ Parser<ManagedTokenSource>::parse_closure_expr 
(AST::AttrVec outer_attrs)
        }
 
       return std::unique_ptr<AST::ClosureExprInnerTyped> (
-       new AST::ClosureExprInnerTyped (std::move (type), std::move (block),
+       new AST::ClosureExprInnerTyped (std::move (type),
+                                       std::move (block.value ()),
                                        std::move (params), locus, has_move,
                                        std::move (outer_attrs)));
     }
@@ -433,7 +435,7 @@ Parser<ManagedTokenSource>::parse_try_expr (AST::AttrVec 
outer_attrs,
       skip_token (TRY);
     }
 
-  std::unique_ptr<AST::BlockExpr> block_expr = parse_block_expr ();
+  auto block_expr = parse_block_expr ();
 
   if (!block_expr)
     {
@@ -445,7 +447,8 @@ Parser<ManagedTokenSource>::parse_try_expr (AST::AttrVec 
outer_attrs,
     }
 
   return std::unique_ptr<AST::TryExpr> (
-    new AST::TryExpr (std::move (block_expr), std::move (outer_attrs), locus));
+    new AST::TryExpr (std::move (block_expr.value ()), std::move (outer_attrs),
+                     locus));
 }
 
 /* Parses a break expression (including any label to break to AND any return
@@ -548,8 +551,8 @@ Parser<ManagedTokenSource>::parse_if_expr (AST::AttrVec 
outer_attrs,
     }
 
   // parse required block expr
-  std::unique_ptr<AST::BlockExpr> if_body = parse_block_expr ();
-  if (if_body == nullptr)
+  auto if_body = parse_block_expr ();
+  if (!if_body)
     return nullptr;
 
   // branch to parse end or else (and then else, else if, or else if let)
@@ -557,7 +560,7 @@ Parser<ManagedTokenSource>::parse_if_expr (AST::AttrVec 
outer_attrs,
     {
       // single selection - end of if expression
       return std::unique_ptr<AST::IfExpr> (
-       new AST::IfExpr (std::move (condition), std::move (if_body),
+       new AST::IfExpr (std::move (condition), std::move (if_body.value ()),
                         std::move (outer_attrs), locus));
     }
   else
@@ -575,8 +578,8 @@ Parser<ManagedTokenSource>::parse_if_expr (AST::AttrVec 
outer_attrs,
          {
            // double selection - else
            // parse else block expr (required)
-           std::unique_ptr<AST::BlockExpr> else_body = parse_block_expr ();
-           if (else_body == nullptr)
+           auto else_body = parse_block_expr ();
+           if (!else_body)
              {
                Error error (lexer.peek_token ()->get_locus (),
                             "failed to parse else body block expression in "
@@ -589,8 +592,8 @@ Parser<ManagedTokenSource>::parse_if_expr (AST::AttrVec 
outer_attrs,
 
            return std::unique_ptr<AST::IfExprConseqElse> (
              new AST::IfExprConseqElse (std::move (condition),
-                                        std::move (if_body),
-                                        std::move (else_body),
+                                        std::move (if_body.value ()),
+                                        std::move (else_body.value ()),
                                         std::move (outer_attrs), locus));
          }
        case IF:
@@ -615,7 +618,7 @@ Parser<ManagedTokenSource>::parse_if_expr (AST::AttrVec 
outer_attrs,
 
                return std::unique_ptr<AST::IfExprConseqElse> (
                  new AST::IfExprConseqElse (std::move (condition),
-                                            std::move (if_body),
+                                            std::move (if_body.value ()),
                                             std::move (if_let_expr),
                                             std::move (outer_attrs), locus));
              }
@@ -636,7 +639,7 @@ Parser<ManagedTokenSource>::parse_if_expr (AST::AttrVec 
outer_attrs,
 
                return std::unique_ptr<AST::IfExprConseqElse> (
                  new AST::IfExprConseqElse (std::move (condition),
-                                            std::move (if_body),
+                                            std::move (if_body.value ()),
                                             std::move (if_expr),
                                             std::move (outer_attrs), locus));
              }
@@ -723,8 +726,8 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec 
outer_attrs,
    * expression here? or actually probably in semantic analysis. */
 
   // parse block expression (required)
-  std::unique_ptr<AST::BlockExpr> if_let_body = parse_block_expr ();
-  if (if_let_body == nullptr)
+  auto if_let_body = parse_block_expr ();
+  if (!if_let_body)
     {
       Error error (
        lexer.peek_token ()->get_locus (),
@@ -739,10 +742,9 @@ Parser<ManagedTokenSource>::parse_if_let_expr 
(AST::AttrVec outer_attrs,
   if (lexer.peek_token ()->get_id () != ELSE)
     {
       // single selection - end of if let expression
-      return std::unique_ptr<AST::IfLetExpr> (
-       new AST::IfLetExpr (std::move (match_arm_pattern),
-                           std::move (scrutinee_expr), std::move (if_let_body),
-                           std::move (outer_attrs), locus));
+      return std::unique_ptr<AST::IfLetExpr> (new AST::IfLetExpr (
+       std::move (match_arm_pattern), std::move (scrutinee_expr),
+       std::move (if_let_body.value ()), std::move (outer_attrs), locus));
     }
   else
     {
@@ -759,8 +761,8 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec 
outer_attrs,
          {
            // double selection - else
            // parse else block expr (required)
-           std::unique_ptr<AST::BlockExpr> else_body = parse_block_expr ();
-           if (else_body == nullptr)
+           auto else_body = parse_block_expr ();
+           if (!else_body)
              {
                Error error (lexer.peek_token ()->get_locus (),
                             "failed to parse else body block expression in "
@@ -774,8 +776,8 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec 
outer_attrs,
            return std::unique_ptr<AST::IfLetExprConseqElse> (
              new AST::IfLetExprConseqElse (std::move (match_arm_pattern),
                                            std::move (scrutinee_expr),
-                                           std::move (if_let_body),
-                                           std::move (else_body),
+                                           std::move (if_let_body.value ()),
+                                           std::move (else_body.value ()),
                                            std::move (outer_attrs), locus));
          }
        case IF:
@@ -801,7 +803,7 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec 
outer_attrs,
                return std::unique_ptr<AST::IfLetExprConseqElse> (
                  new AST::IfLetExprConseqElse (
                    std::move (match_arm_pattern), std::move (scrutinee_expr),
-                   std::move (if_let_body), std::move (if_let_expr),
+                   std::move (if_let_body.value ()), std::move (if_let_expr),
                    std::move (outer_attrs), locus));
              }
            else
@@ -822,7 +824,7 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec 
outer_attrs,
                return std::unique_ptr<AST::IfLetExprConseqElse> (
                  new AST::IfLetExprConseqElse (
                    std::move (match_arm_pattern), std::move (scrutinee_expr),
-                   std::move (if_let_body), std::move (if_expr),
+                   std::move (if_let_body.value ()), std::move (if_expr),
                    std::move (outer_attrs), locus));
              }
          }
@@ -871,12 +873,12 @@ Parser<ManagedTokenSource>::parse_loop_expr (AST::AttrVec 
outer_attrs,
     }
 
   // parse loop body, which is required
-  std::unique_ptr<AST::BlockExpr> loop_body = parse_block_expr ();
-  if (loop_body == nullptr)
+  auto loop_body = parse_block_expr ();
+  if (!loop_body)
     return nullptr;
 
   return std::unique_ptr<AST::LoopExpr> (
-    new AST::LoopExpr (std::move (loop_body), locus, std::move (label),
+    new AST::LoopExpr (std::move (loop_body.value ()), locus, std::move 
(label),
                       std::move (outer_attrs)));
 }
 
@@ -937,8 +939,8 @@ Parser<ManagedTokenSource>::parse_while_loop_expr (
    * semantic analysis */
 
   // parse loop body (required)
-  std::unique_ptr<AST::BlockExpr> body = parse_block_expr ();
-  if (body == nullptr)
+  auto body = parse_block_expr ();
+  if (!body)
     {
       Error error (lexer.peek_token ()->get_locus (),
                   "failed to parse loop body block expression in while loop");
@@ -949,8 +951,8 @@ Parser<ManagedTokenSource>::parse_while_loop_expr (
     }
 
   return std::unique_ptr<AST::WhileLoopExpr> (
-    new AST::WhileLoopExpr (std::move (predicate), std::move (body), locus,
-                           std::move (label), std::move (outer_attrs)));
+    new AST::WhileLoopExpr (std::move (predicate), std::move (body.value ()),
+                           locus, std::move (label), std::move (outer_attrs)));
 }
 
 /* Parses a "while let" loop expression. Label is not parsed and should be
@@ -1018,8 +1020,8 @@ Parser<ManagedTokenSource>::parse_while_let_loop_expr (
    * semantic analysis. */
 
   // parse loop body, which is required
-  std::unique_ptr<AST::BlockExpr> body = parse_block_expr ();
-  if (body == nullptr)
+  auto body = parse_block_expr ();
+  if (!body)
     {
       Error error (lexer.peek_token ()->get_locus (),
                   "failed to parse block expr (loop body) of while let loop");
@@ -1029,9 +1031,11 @@ Parser<ManagedTokenSource>::parse_while_let_loop_expr (
       return nullptr;
     }
 
-  return std::unique_ptr<AST::WhileLetLoopExpr> (new AST::WhileLetLoopExpr (
-    std::move (predicate_pattern), std::move (predicate_expr), std::move 
(body),
-    locus, std::move (label), std::move (outer_attrs)));
+  return std::unique_ptr<AST::WhileLetLoopExpr> (
+    new AST::WhileLetLoopExpr (std::move (predicate_pattern),
+                              std::move (predicate_expr),
+                              std::move (body.value ()), locus,
+                              std::move (label), std::move (outer_attrs)));
 }
 
 /* Parses a "for" iterative loop. Label is not parsed and should be parsed via
@@ -1083,8 +1087,8 @@ Parser<ManagedTokenSource>::parse_for_loop_expr (
   // TODO: check to ensure this isn't struct expr? Or in semantic analysis.
 
   // parse loop body, which is required
-  std::unique_ptr<AST::BlockExpr> body = parse_block_expr ();
-  if (body == nullptr)
+  auto body = parse_block_expr ();
+  if (!body)
     {
       Error error (lexer.peek_token ()->get_locus (),
                   "failed to parse loop body block expression in for loop");
@@ -1093,10 +1097,9 @@ Parser<ManagedTokenSource>::parse_for_loop_expr (
       // skip somewhere?
       return nullptr;
     }
-
   return std::unique_ptr<AST::ForLoopExpr> (
     new AST::ForLoopExpr (std::move (pattern), std::move (expr),
-                         std::move (body), locus, std::move (label),
+                         std::move (body.value ()), locus, std::move (label),
                          std::move (outer_attrs)));
 }
 
@@ -1161,7 +1164,14 @@ Parser<ManagedTokenSource>::parse_labelled_loop_expr 
(const_TokenPtr tok,
                                        std::move (label));
        }
     case LEFT_CURLY:
-      return parse_block_expr (std::move (outer_attrs), std::move (label));
+      {
+       auto block
+         = parse_block_expr (std::move (outer_attrs), std::move (label));
+       if (block)
+         return std::move (block.value ());
+       else
+         return nullptr;
+      }
     default:
       // error
       add_error (Error (t->get_locus (),
@@ -1316,8 +1326,8 @@ Parser<ManagedTokenSource>::parse_async_block_expr 
(AST::AttrVec outer_attrs)
     }
 
   // parse block expression (required)
-  std::unique_ptr<AST::BlockExpr> block_expr = parse_block_expr ();
-  if (block_expr == nullptr)
+  auto block_expr = parse_block_expr ();
+  if (!block_expr)
     {
       Error error (
        lexer.peek_token ()->get_locus (),
@@ -1329,7 +1339,7 @@ Parser<ManagedTokenSource>::parse_async_block_expr 
(AST::AttrVec outer_attrs)
     }
 
   return std::unique_ptr<AST::AsyncBlockExpr> (
-    new AST::AsyncBlockExpr (std::move (block_expr), has_move,
+    new AST::AsyncBlockExpr (std::move (block_expr.value ()), has_move,
                             std::move (outer_attrs), locus));
 }
 
@@ -1347,8 +1357,8 @@ Parser<ManagedTokenSource>::parse_unsafe_block_expr (
     }
 
   // parse block expression (required)
-  std::unique_ptr<AST::BlockExpr> block_expr = parse_block_expr ();
-  if (block_expr == nullptr)
+  auto block_expr = parse_block_expr ();
+  if (!block_expr)
     {
       Error error (
        lexer.peek_token ()->get_locus (),
@@ -1358,10 +1368,9 @@ Parser<ManagedTokenSource>::parse_unsafe_block_expr (
       // skip somewhere?
       return nullptr;
     }
-
   return std::unique_ptr<AST::UnsafeBlockExpr> (
-    new AST::UnsafeBlockExpr (std::move (block_expr), std::move (outer_attrs),
-                             locus));
+    new AST::UnsafeBlockExpr (std::move (block_expr.value ()),
+                             std::move (outer_attrs), locus));
 }
 
 // Parses an array definition expression.
@@ -2204,8 +2213,14 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
       return parse_continue_expr (std::move (outer_attrs), tok->get_locus ());
     case LEFT_CURLY:
       // ok - this is an expression with block for once.
-      return parse_block_expr (std::move (outer_attrs), tl::nullopt,
-                              tok->get_locus ());
+      {
+       auto block = parse_block_expr (std::move (outer_attrs), tl::nullopt,
+                                      tok->get_locus ());
+       if (block)
+         return std::move (block.value ());
+       else
+         return nullptr;
+      }
     case IF:
       // if or if let, so more lookahead to find out
       if (lexer.peek_token ()->get_id () == LET)
@@ -4065,8 +4080,8 @@ Parser<ManagedTokenSource>::parse_closure_expr_pratt 
(const_TokenPtr tok,
        }
 
       // parse block expr, which is required
-      std::unique_ptr<AST::BlockExpr> block = parse_block_expr ();
-      if (block == nullptr)
+      auto block = parse_block_expr ();
+      if (!block)
        {
          // error
          Error error (lexer.peek_token ()->get_locus (),
@@ -4078,7 +4093,8 @@ Parser<ManagedTokenSource>::parse_closure_expr_pratt 
(const_TokenPtr tok,
        }
 
       return std::unique_ptr<AST::ClosureExprInnerTyped> (
-       new AST::ClosureExprInnerTyped (std::move (type), std::move (block),
+       new AST::ClosureExprInnerTyped (std::move (type),
+                                       std::move (block.value ()),
                                        std::move (params), locus, has_move,
                                        std::move (outer_attrs)));
     }
diff --git a/gcc/rust/parse/rust-parse-impl.hxx 
b/gcc/rust/parse/rust-parse-impl.hxx
index 20754063f..6fcbcb1b6 100644
--- a/gcc/rust/parse/rust-parse-impl.hxx
+++ b/gcc/rust/parse/rust-parse-impl.hxx
@@ -1627,10 +1627,10 @@ Parser<ManagedTokenSource>::parse_function 
(AST::Visibility vis,
     lexer.skip_token ();
   else
     {
-      std::unique_ptr<AST::BlockExpr> block_expr = parse_block_expr ();
-      if (block_expr == nullptr)
+      auto block_expr = parse_block_expr ();
+      if (!block_expr)
        return nullptr;
-      body = std::move (block_expr);
+      body = std::move (block_expr.value ());
     }
 
   return std::unique_ptr<AST::Function> (
@@ -4338,7 +4338,7 @@ 
Parser<ManagedTokenSource>::parse_inherent_impl_function_or_method (
     {
       auto result = parse_block_expr ();
 
-      if (result == nullptr)
+      if (!result)
        {
          Error error (
            lexer.peek_token ()->get_locus (),
@@ -4349,7 +4349,7 @@ 
Parser<ManagedTokenSource>::parse_inherent_impl_function_or_method (
          skip_after_end_block ();
          return nullptr;
        }
-      body = std::move (result);
+      body = std::move (result.value ());
     }
 
   return std::unique_ptr<AST::Function> (
@@ -4576,7 +4576,7 @@ 
Parser<ManagedTokenSource>::parse_trait_impl_function_or_method (
   else
     {
       auto result = parse_block_expr ();
-      if (result == nullptr)
+      if (!result)
        {
          Error error (lexer.peek_token ()->get_locus (),
                       "could not parse definition in trait impl %s definition",
@@ -4586,7 +4586,7 @@ 
Parser<ManagedTokenSource>::parse_trait_impl_function_or_method (
          skip_after_end_block ();
          return nullptr;
        }
-      body = std::move (result);
+      body = std::move (result.value ());
     }
 
   return std::unique_ptr<AST::Function> (
@@ -4890,7 +4890,13 @@ Parser<ManagedTokenSource>::parse_let_stmt (AST::AttrVec 
outer_attrs,
 
   tl::optional<std::unique_ptr<AST::Expr>> else_expr = tl::nullopt;
   if (maybe_skip_token (ELSE))
-    else_expr = parse_block_expr ();
+    {
+      auto block_expr = parse_block_expr ();
+      if (block_expr)
+       else_expr = tl::optional{std::move (block_expr.value ())};
+      else
+       else_expr = tl::nullopt;
+    }
 
   if (restrictions.consume_semi)
     {
@@ -4956,7 +4962,7 @@ Parser<ManagedTokenSource>::parse_generic_arg ()
                                                  tok->get_locus ());
       }
     case LEFT_CURLY:
-      expr = parse_block_expr ();
+      expr = parse_block_expr ().value ();
       break;
     case MINUS:
     case STRING_LITERAL:
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 95745a60c..2ca1c587c 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -244,7 +244,7 @@ public:
   std::unique_ptr<AST::LiteralExpr> parse_literal_expr (AST::AttrVec 
outer_attrs
                                                        = AST::AttrVec ());
 
-  std::unique_ptr<AST::BlockExpr>
+  tl::expected<std::unique_ptr<AST::BlockExpr>, Parse::Error::BlockExpr>
   parse_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
                    tl::optional<AST::LoopLabel> = tl::nullopt,
                    location_t pratt_parsed_loc = UNKNOWN_LOCATION);
-- 
2.52.0

Reply via email to