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

Some error types in the parser had the exact same meaning and could be
grouped under one same type.

gcc/rust/ChangeLog:

        * ast/rust-ast.cc (AttributeParser::parse_meta_item_lit): Use
        tl::expected
        * expand/rust-macro-builtins-helpers.cc (parse_single_string_literal):
        Likewise.
        * expand/rust-macro-expand.cc (MacroExpander::match_fragment):
        Likewise.
        * parse/rust-cfg-parser.cc (parse_cfg_option): Likewise.
        * parse/rust-parse-error.h (struct SimplePath): Remove error type.
        (struct DelimTokenTree): Likewise.
        (struct Token): Likewise.
        (struct TokenTree): Likewise.
        (class LifetimeParam): Move from here ...
        (struct LifetimeParam): ... to here. Add ctor.
        (class Lifetime): Add error type.
        (enum class): Remove AnonConst.
        (struct BlockExpr): Change BlockExpr to generic node error.
        * parse/rust-parse-impl-expr.hxx: Use tl::expected for errors.
        * parse/rust-parse-impl-path.hxx: Likewise.
        * parse/rust-parse-impl-ttree.hxx: Likewise.
        * parse/rust-parse-impl.hxx: Likewise.
        * parse/rust-parse.h: Update function return types with tl::expected
        to propagate errors.

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/fd5517148d069cd2367cc5653913b1b9fa4f91a8

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

 gcc/rust/ast/rust-ast.cc                      |   4 +-
 .../expand/rust-macro-builtins-helpers.cc     |   2 +-
 gcc/rust/expand/rust-macro-expand.cc          |   2 +-
 gcc/rust/parse/rust-cfg-parser.cc             |   5 +-
 gcc/rust/parse/rust-parse-error.h             | 133 +++---------------
 gcc/rust/parse/rust-parse-impl-expr.hxx       |  48 ++++---
 gcc/rust/parse/rust-parse-impl-path.hxx       |   8 +-
 gcc/rust/parse/rust-parse-impl-ttree.hxx      |  15 +-
 gcc/rust/parse/rust-parse-impl.hxx            |  22 ++-
 gcc/rust/parse/rust-parse.h                   |  26 ++--
 10 files changed, 97 insertions(+), 168 deletions(-)

diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 509631ff2..b9f7d280d 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -3813,7 +3813,7 @@ DelimTokenTree::to_token_stream () const
 std::unique_ptr<MetaItemLitExpr>
 AttributeParser::parse_meta_item_lit ()
 {
-  std::unique_ptr<LiteralExpr> lit_expr = parser->parse_literal_expr ({});
+  auto lit_expr = parser->parse_literal_expr ({});
 
   // TODO: return nullptr instead?
   if (!lit_expr)
@@ -3822,7 +3822,7 @@ AttributeParser::parse_meta_item_lit ()
                       lexer->peek_token ()->get_locus ()));
 
   return std::unique_ptr<MetaItemLitExpr> (
-    new MetaItemLitExpr (std::move (*lit_expr)));
+    new MetaItemLitExpr (std::move (*lit_expr.value ())));
 }
 
 bool
diff --git a/gcc/rust/expand/rust-macro-builtins-helpers.cc 
b/gcc/rust/expand/rust-macro-builtins-helpers.cc
index 1c092af74..2e5710c3b 100644
--- a/gcc/rust/expand/rust-macro-builtins-helpers.cc
+++ b/gcc/rust/expand/rust-macro-builtins-helpers.cc
@@ -188,7 +188,7 @@ parse_single_string_literal (BuiltinMacro kind,
 
   if (parser.peek_current_token ()->get_id () == STRING_LITERAL)
     {
-      lit_expr = parser.parse_literal_expr ();
+      lit_expr = parser.parse_literal_expr ().value ();
       parser.maybe_skip_token (COMMA);
       if (parser.peek_current_token ()->get_id () != last_token_id)
        {
diff --git a/gcc/rust/expand/rust-macro-expand.cc 
b/gcc/rust/expand/rust-macro-expand.cc
index 4d658fcd5..a37252644 100644
--- a/gcc/rust/expand/rust-macro-expand.cc
+++ b/gcc/rust/expand/rust-macro-expand.cc
@@ -434,7 +434,7 @@ MacroExpander::match_fragment (Parser<MacroInvocLexer> 
&parser,
       break;
 
     case AST::MacroFragSpec::LITERAL:
-      parser.parse_literal_expr ();
+      std::ignore = parser.parse_literal_expr ();
       break;
 
     case AST::MacroFragSpec::ITEM:
diff --git a/gcc/rust/parse/rust-cfg-parser.cc 
b/gcc/rust/parse/rust-cfg-parser.cc
index f85939985..b1592d7d3 100644
--- a/gcc/rust/parse/rust-cfg-parser.cc
+++ b/gcc/rust/parse/rust-cfg-parser.cc
@@ -51,10 +51,11 @@ parse_cfg_option (std::string &input, std::string &key, 
std::string &value)
       {
        rust_assert (parser.skip_token (EQUAL));
 
-       auto value_expr = parser.parse_literal_expr ();
+       auto value_expr_res = parser.parse_literal_expr ();
        // We had an equal sign but no value, error out
-       if (!value_expr)
+       if (!value_expr_res)
          return false;
+       auto value_expr = std::move (value_expr_res.value ());
 
        if (value_expr->get_lit_type () != AST::Literal::LitType::STRING)
          return false;
diff --git a/gcc/rust/parse/rust-parse-error.h 
b/gcc/rust/parse/rust-parse-error.h
index c5a52becd..4d2d0e1c1 100644
--- a/gcc/rust/parse/rust-parse-error.h
+++ b/gcc/rust/parse/rust-parse-error.h
@@ -55,22 +55,6 @@ private:
   Attribute (Kind kind) : kind (kind) {}
 };
 
-struct SimplePath
-{
-  static tl::expected<AST::SimplePath, SimplePath> make_malformed ()
-  {
-    return tl::unexpected<SimplePath> (SimplePath (Kind::MALFORMED));
-  }
-
-  enum class Kind
-  {
-    MALFORMED,
-  } kind;
-
-private:
-  SimplePath (Kind kind) : kind (kind) {}
-};
-
 struct AttributeBody
 {
   static tl::expected<Parse::AttributeBody, AttributeBody> make_invalid_path ()
@@ -172,81 +156,6 @@ private:
   AttrInput (Kind kind) : kind (kind) {}
 };
 
-struct DelimTokenTree
-{
-  static tl::expected<AST::DelimTokenTree, DelimTokenTree>
-  make_expected_delimiter ()
-  {
-    return tl::unexpected<DelimTokenTree> (
-      DelimTokenTree (Kind::EXPECTED_DELIMITER));
-  }
-
-  static tl::expected<AST::DelimTokenTree, DelimTokenTree>
-  make_invalid_token_tree ()
-  {
-    return tl::unexpected<DelimTokenTree> (
-      DelimTokenTree (Kind::INVALID_TOKEN_TREE));
-  }
-
-  static tl::expected<AST::DelimTokenTree, DelimTokenTree>
-  make_mismatched_delimiters ()
-  {
-    return tl::unexpected<DelimTokenTree> (
-      DelimTokenTree (Kind::INVALID_TOKEN_TREE));
-  }
-
-  enum class Kind
-  {
-    EXPECTED_DELIMITER,
-    INVALID_TOKEN_TREE,
-    MISMATCHED_DELIMITERS,
-  } kind;
-
-private:
-  DelimTokenTree (Kind kind) : kind (kind) {}
-};
-
-struct Token
-{
-  static tl::expected<std::unique_ptr<AST::Token>, Token> make_malformed ()
-  {
-    return tl::unexpected<Token> (Token (Kind::MALFORMED));
-  }
-
-  enum class Kind
-  {
-    MALFORMED,
-  } kind;
-
-private:
-  Token (Kind kind) : kind (kind) {}
-};
-
-struct TokenTree
-{
-  static tl::expected<std::unique_ptr<AST::TokenTree>, TokenTree>
-  make_malformed ()
-  {
-    return tl::unexpected<TokenTree> (TokenTree (Kind::MALFORMED));
-  }
-
-  static tl::expected<std::unique_ptr<AST::TokenTree>, TokenTree>
-  make_malformed_delimited_token_tree ()
-  {
-    return tl::unexpected<TokenTree> (
-      TokenTree (Kind::MALFORMED_DELIMITED_TOKEN_TREE));
-  }
-
-  enum class Kind
-  {
-    MALFORMED,
-    MALFORMED_DELIMITED_TOKEN_TREE,
-  } kind;
-
-private:
-  TokenTree (Kind kind) : kind (kind) {}
-};
-
 struct Item
 {
   static tl::expected<std::unique_ptr<AST::Item>, Item> make_end_of_file ()
@@ -319,17 +228,26 @@ private:
   Visibility (Kind kind) : kind (kind) {}
 };
 
-class LifetimeParam
+struct LifetimeParam
 {
-};
+  static tl::expected<AST::LifetimeParam, LifetimeParam>
+  make_not_a_lifetime_param ()
+  {
+    return tl::unexpected<LifetimeParam> (
+      LifetimeParam (Kind::NOT_A_LIFETIME_PARAM));
+  }
 
-class Lifetime
-{
+  enum class Kind
+  {
+    NOT_A_LIFETIME_PARAM,
+  } kind;
+
+private:
+  LifetimeParam (Kind kind) : kind (kind) {}
 };
 
-enum class AnonConst
+class Lifetime
 {
-  InvalidSizeExpr,
 };
 
 struct LoopLabel
@@ -385,21 +303,14 @@ private:
   Self (Kind kind) : kind (kind) {}
 };
 
-struct BlockExpr
+// Generic intermediate AST node error used when the errors need no special
+// handling
+enum class Node
 {
-  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) {}
+  // Unexpected or missing token whilst parsing the node
+  MALFORMED,
+  // Error whilst parsing a child construct for the current node
+  CHILD_ERROR,
 };
 
 } // namespace Error
diff --git a/gcc/rust/parse/rust-parse-impl-expr.hxx 
b/gcc/rust/parse/rust-parse-impl-expr.hxx
index 99fb3cfa0..4eae47cfd 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>
-tl::expected<std::unique_ptr<AST::BlockExpr>, Parse::Error::BlockExpr>
+tl::expected<std::unique_ptr<AST::BlockExpr>, Parse::Error::Node>
 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 Parse::Error::BlockExpr::make_malformed ();
+         return tl::unexpected (Parse::Error::Node::MALFORMED);
        }
     }
 
@@ -55,7 +55,7 @@ Parser<ManagedTokenSource>::parse_block_expr (
       if (expr_or_stmt.is_error ())
        {
          skip_after_end_block ();
-         return Parse::Error::BlockExpr::make_malformed ();
+         return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
        }
 
       t = lexer.peek_token ();
@@ -82,7 +82,7 @@ Parser<ManagedTokenSource>::parse_block_expr (
       add_error (std::move (error));
 
       skip_after_end_block ();
-      return Parse::Error::BlockExpr::make_malformed ();
+      return tl::unexpected (Parse::Error::Node::MALFORMED);
     }
 
   // grammar allows for empty block expressions
@@ -98,7 +98,7 @@ Parser<ManagedTokenSource>::parse_block_expr (
 /* Parse an anonymous const expression. This can be a regular const expression
  * or an underscore for deferred const inference */
 template <typename ManagedTokenSource>
-tl::expected<AST::AnonConst, Parse::Error::AnonConst>
+tl::expected<AST::AnonConst, Parse::Error::Node>
 Parser<ManagedTokenSource>::parse_anon_const ()
 {
   auto current = lexer.peek_token ();
@@ -111,7 +111,7 @@ Parser<ManagedTokenSource>::parse_anon_const ()
   auto expr = parse_expr ();
 
   if (!expr)
-    return tl::make_unexpected (Parse::Error::AnonConst::InvalidSizeExpr);
+    return tl::make_unexpected (Parse::Error::Node{});
 
   return AST::AnonConst (std::move (expr), locus);
 }
@@ -119,7 +119,7 @@ Parser<ManagedTokenSource>::parse_anon_const ()
 /* Parse a "const block", a block preceded by the `const` keyword whose
  * statements can be const evaluated and used in constant contexts */
 template <typename ManagedTokenSource>
-std::unique_ptr<AST::ConstBlock>
+tl::expected<std::unique_ptr<AST::ConstBlock>, Parse::Error::Node>
 Parser<ManagedTokenSource>::parse_const_block_expr (AST::AttrVec outer_attrs,
                                                    location_t locus)
 {
@@ -130,7 +130,7 @@ Parser<ManagedTokenSource>::parse_const_block_expr 
(AST::AttrVec outer_attrs,
       add_error (Error (locus, "failed to parse inner block in const block"));
       skip_after_end_block ();
 
-      return nullptr;
+      return tl::unexpected (Parse::Error::Node{});
     }
   auto block = std::move (block_res.value ());
 
@@ -144,7 +144,7 @@ Parser<ManagedTokenSource>::parse_const_block_expr 
(AST::AttrVec outer_attrs,
 /* Parses a "grouped" expression (expression in parentheses), used to control
  * precedence. */
 template <typename ManagedTokenSource>
-std::unique_ptr<AST::GroupedExpr>
+tl::expected<std::unique_ptr<AST::GroupedExpr>, Parse::Error::Node>
 Parser<ManagedTokenSource>::parse_grouped_expr (AST::AttrVec outer_attrs)
 {
   location_t locus = lexer.peek_token ()->get_locus ();
@@ -154,17 +154,17 @@ Parser<ManagedTokenSource>::parse_grouped_expr 
(AST::AttrVec outer_attrs)
 
   // parse required expr inside parentheses
   std::unique_ptr<AST::Expr> expr_in_parens = parse_expr ();
-  if (expr_in_parens == nullptr)
+  if (!expr_in_parens)
     {
       // skip after somewhere?
       // error?
-      return nullptr;
+      return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
     }
 
   if (!skip_token (RIGHT_PAREN))
     {
       // skip after somewhere?
-      return nullptr;
+      return tl::unexpected (Parse::Error::Node::MALFORMED);
     }
 
   return std::unique_ptr<AST::GroupedExpr> (
@@ -174,7 +174,7 @@ Parser<ManagedTokenSource>::parse_grouped_expr 
(AST::AttrVec outer_attrs)
 
 // Parses a closure expression (closure definition).
 template <typename ManagedTokenSource>
-std::unique_ptr<AST::ClosureExpr>
+tl::expected<std::unique_ptr<AST::ClosureExpr>, Parse::Error::Node>
 Parser<ManagedTokenSource>::parse_closure_expr (AST::AttrVec outer_attrs)
 {
   location_t locus = lexer.peek_token ()->get_locus ();
@@ -234,7 +234,7 @@ Parser<ManagedTokenSource>::parse_closure_expr 
(AST::AttrVec outer_attrs)
                        t->get_token_description ()));
 
       // skip somewhere?
-      return nullptr;
+      return tl::unexpected (Parse::Error::Node::MALFORMED);
     }
 
   // again branch based on next token
@@ -255,7 +255,7 @@ Parser<ManagedTokenSource>::parse_closure_expr 
(AST::AttrVec outer_attrs)
          add_error (std::move (error));
 
          // skip somewhere?
-         return nullptr;
+         return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
        }
 
       // parse block expr, which is required
@@ -268,7 +268,7 @@ Parser<ManagedTokenSource>::parse_closure_expr 
(AST::AttrVec outer_attrs)
          add_error (std::move (error));
 
          // skip somewhere?
-         return nullptr;
+         return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
        }
 
       return std::unique_ptr<AST::ClosureExprInnerTyped> (
@@ -290,7 +290,7 @@ Parser<ManagedTokenSource>::parse_closure_expr 
(AST::AttrVec outer_attrs)
          add_error (std::move (error));
 
          // skip somewhere?
-         return nullptr;
+         return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
        }
 
       return std::unique_ptr<AST::ClosureExprInner> (
@@ -301,7 +301,7 @@ Parser<ManagedTokenSource>::parse_closure_expr 
(AST::AttrVec outer_attrs)
 
 // Parses a literal token (to literal expression).
 template <typename ManagedTokenSource>
-std::unique_ptr<AST::LiteralExpr>
+tl::expected<std::unique_ptr<AST::LiteralExpr>, Parse::Error::Node>
 Parser<ManagedTokenSource>::parse_literal_expr (AST::AttrVec outer_attrs)
 {
   // TODO: change if literal representation in lexer changes
@@ -367,7 +367,7 @@ Parser<ManagedTokenSource>::parse_literal_expr 
(AST::AttrVec outer_attrs)
                        t->get_token_description ()));
 
       // skip?
-      return nullptr;
+      return tl::unexpected (Parse::Error::Node::MALFORMED);
     }
 
   // create literal based on stuff in switch
@@ -2268,8 +2268,14 @@ Parser<ManagedTokenSource>::null_denotation_not_path (
               tok->get_token_description ()));
       return nullptr;
     case CONST:
-      return parse_const_block_expr (std::move (outer_attrs),
-                                    tok->get_locus ());
+      {
+       auto const_block
+         = parse_const_block_expr (std::move (outer_attrs), tok->get_locus ());
+       if (const_block)
+         return std::move (const_block.value ());
+       else
+         return nullptr;
+      }
     default:
       if (!restrictions.expr_can_be_null)
        add_error (Error (tok->get_locus (),
diff --git a/gcc/rust/parse/rust-parse-impl-path.hxx 
b/gcc/rust/parse/rust-parse-impl-path.hxx
index dd52dccba..53f4d6497 100644
--- a/gcc/rust/parse/rust-parse-impl-path.hxx
+++ b/gcc/rust/parse/rust-parse-impl-path.hxx
@@ -26,7 +26,7 @@ namespace Rust {
 
 // Parses a SimplePath AST node, if it exists. Does nothing otherwise.
 template <typename ManagedTokenSource>
-tl::expected<AST::SimplePath, Parse::Error::SimplePath>
+tl::expected<AST::SimplePath, Parse::Error::Node>
 Parser<ManagedTokenSource>::parse_simple_path ()
 {
   bool has_opening_scope_resolution = false;
@@ -37,7 +37,7 @@ Parser<ManagedTokenSource>::parse_simple_path ()
   // don't parse anything if not a path upfront
   if (!is_simple_path_segment (lexer.peek_token ()->get_id ())
       && !is_simple_path_segment (lexer.peek_token (1)->get_id ()))
-    return Parse::Error::SimplePath::make_malformed ();
+    return tl::unexpected (Parse::Error::Node::MALFORMED);
 
   /* Checks for opening scope resolution (i.e. global scope fully-qualified
    * path) */
@@ -54,7 +54,7 @@ Parser<ManagedTokenSource>::parse_simple_path ()
   auto segment = parse_simple_path_segment ();
 
   if (!segment)
-    return Parse::Error::SimplePath::make_malformed ();
+    return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
 
   // get location if not gotten already
   if (locus == UNKNOWN_LOCATION)
@@ -75,7 +75,7 @@ Parser<ManagedTokenSource>::parse_simple_path ()
          if (new_segment.error ().kind == Error::INVALID_SIMPLE_PATH_TOKEN)
            break; /* Could be end of path */
          else     /* Any other error is an hard error */
-           return Parse::Error::SimplePath::make_malformed ();
+           return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
        }
 
       segments.push_back (std::move (new_segment.value ()));
diff --git a/gcc/rust/parse/rust-parse-impl-ttree.hxx 
b/gcc/rust/parse/rust-parse-impl-ttree.hxx
index ab05cb27f..4c539d17e 100644
--- a/gcc/rust/parse/rust-parse-impl-ttree.hxx
+++ b/gcc/rust/parse/rust-parse-impl-ttree.hxx
@@ -29,7 +29,7 @@ namespace Rust {
 /* Parses a TokenTree syntactical production. This is either a delimited token
  * tree or a non-delimiter token. */
 template <typename ManagedTokenSource>
-tl::expected<std::unique_ptr<AST::TokenTree>, Parse::Error::TokenTree>
+tl::expected<std::unique_ptr<AST::TokenTree>, Parse::Error::Node>
 Parser<ManagedTokenSource>::parse_token_tree ()
 {
   const_TokenPtr t = lexer.peek_token ();
@@ -43,8 +43,7 @@ Parser<ManagedTokenSource>::parse_token_tree ()
        // Parse delimited token tree
        auto delim_token_tree = parse_delim_token_tree ();
        if (!delim_token_tree)
-         return Parse::Error::TokenTree::
-           make_malformed_delimited_token_tree ();
+         return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
 
        // TODO: use move rather than copy constructor
        return std::unique_ptr<AST::DelimTokenTree> (
@@ -62,7 +61,7 @@ Parser<ManagedTokenSource>::parse_token_tree ()
                        "non-delimiter tokens"));
 
       lexer.skip_token ();
-      return Parse::Error::TokenTree::make_malformed ();
+      return tl::unexpected (Parse::Error::Node::MALFORMED);
     default:
       // parse token itself as TokenTree
       lexer.skip_token ();
@@ -72,7 +71,7 @@ Parser<ManagedTokenSource>::parse_token_tree ()
 
 // Parses a delimited token tree
 template <typename ManagedTokenSource>
-tl::expected<AST::DelimTokenTree, Parse::Error::DelimTokenTree>
+tl::expected<AST::DelimTokenTree, Parse::Error::Node>
 Parser<ManagedTokenSource>::parse_delim_token_tree ()
 {
   const_TokenPtr t = lexer.peek_token ();
@@ -100,7 +99,7 @@ Parser<ManagedTokenSource>::parse_delim_token_tree ()
                        "delimited token tree)",
                        t->get_token_description ()));
 
-      return Parse::Error::DelimTokenTree::make_expected_delimiter ();
+      return tl::unexpected (Parse::Error::Node::MALFORMED);
     }
 
   // parse actual token tree vector - 0 or more
@@ -116,7 +115,7 @@ Parser<ManagedTokenSource>::parse_delim_token_tree ()
     {
       auto tok_tree = parse_token_tree ();
       if (!tok_tree)
-       return Parse::Error::DelimTokenTree::make_invalid_token_tree ();
+       return tl::unexpected (Parse::Error::Node::CHILD_ERROR);
 
       token_trees_in_tree.push_back (std::move (tok_tree.value ()));
 
@@ -151,7 +150,7 @@ Parser<ManagedTokenSource>::parse_delim_token_tree ()
                      : (delim_type == AST::SQUARE ? "]" : "}")));
       add_error (std::move (error));
 
-      return Parse::Error::DelimTokenTree::make_mismatched_delimiters ();
+      return tl::unexpected (Parse::Error::Node::MALFORMED);
     }
 }
 
diff --git a/gcc/rust/parse/rust-parse-impl.hxx 
b/gcc/rust/parse/rust-parse-impl.hxx
index 6fcbcb1b6..1be2a5c28 100644
--- a/gcc/rust/parse/rust-parse-impl.hxx
+++ b/gcc/rust/parse/rust-parse-impl.hxx
@@ -314,7 +314,7 @@ Parser<ManagedTokenSource>::parse_crate ()
 
 // Parses an identifier/keyword as a Token
 template <typename ManagedTokenSource>
-tl::expected<std::unique_ptr<AST::Token>, Parse::Error::Token>
+tl::expected<std::unique_ptr<AST::Token>, Parse::Error::Node>
 Parser<ManagedTokenSource>::parse_identifier_or_keyword_token ()
 {
   const_TokenPtr t = lexer.peek_token ();
@@ -327,7 +327,7 @@ 
Parser<ManagedTokenSource>::parse_identifier_or_keyword_token ()
   else
     {
       add_error (Error (t->get_locus (), "expected keyword or identifier"));
-      return Parse::Error::Token::make_malformed ();
+      return tl::unexpected (Parse::Error::Node::MALFORMED);
     }
 }
 
@@ -2156,7 +2156,7 @@ Parser<ManagedTokenSource>::parse_lifetime_param ()
   if (lifetime_tok->get_id () != LIFETIME)
     {
       // if lifetime is missing, must not be a lifetime param, so return error
-      return tl::make_unexpected<Parse::Error::LifetimeParam> ({});
+      return Parse::Error::LifetimeParam::make_not_a_lifetime_param ();
     }
   lexer.skip_token ();
   AST::Lifetime lifetime (AST::Lifetime::NAMED, lifetime_tok->get_str (),
@@ -4962,7 +4962,13 @@ Parser<ManagedTokenSource>::parse_generic_arg ()
                                                  tok->get_locus ());
       }
     case LEFT_CURLY:
-      expr = parse_block_expr ().value ();
+      {
+       auto res = parse_block_expr ();
+       if (res)
+         expr = std::move (res.value ());
+       else
+         return tl::nullopt;
+      }
       break;
     case MINUS:
     case STRING_LITERAL:
@@ -4971,7 +4977,13 @@ Parser<ManagedTokenSource>::parse_generic_arg ()
     case FLOAT_LITERAL:
     case TRUE_LITERAL:
     case FALSE_LITERAL:
-      expr = parse_literal_expr ();
+      {
+       auto res = parse_literal_expr ();
+       if (res)
+         expr = std::move (res.value ());
+       else
+         return tl::nullopt;
+      }
       break;
     // FIXME: Because of this, error reporting is garbage for const generic
     // parameter's default values
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 2ca1c587c..cf26cc2da 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -241,17 +241,17 @@ public:
   parse_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
              ParseRestrictions restrictions = ParseRestrictions ());
 
-  std::unique_ptr<AST::LiteralExpr> parse_literal_expr (AST::AttrVec 
outer_attrs
-                                                       = AST::AttrVec ());
+  tl::expected<std::unique_ptr<AST::LiteralExpr>, Parse::Error::Node>
+  parse_literal_expr (AST::AttrVec outer_attrs = AST::AttrVec ());
 
-  tl::expected<std::unique_ptr<AST::BlockExpr>, Parse::Error::BlockExpr>
+  tl::expected<std::unique_ptr<AST::BlockExpr>, Parse::Error::Node>
   parse_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
                    tl::optional<AST::LoopLabel> = tl::nullopt,
                    location_t pratt_parsed_loc = UNKNOWN_LOCATION);
 
-  tl::expected<AST::AnonConst, Parse::Error::AnonConst> parse_anon_const ();
+  tl::expected<AST::AnonConst, Parse::Error::Node> parse_anon_const ();
 
-  std::unique_ptr<AST::ConstBlock>
+  tl::expected<std::unique_ptr<AST::ConstBlock>, Parse::Error::Node>
   parse_const_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
                          location_t loc = UNKNOWN_LOCATION);
 
@@ -281,9 +281,9 @@ public:
   std::vector<std::unique_ptr<AST::LifetimeParam>> parse_lifetime_params ();
   tl::expected<AST::Visibility, Parse::Error::Visibility> parse_visibility ();
   std::unique_ptr<AST::IdentifierPattern> parse_identifier_pattern ();
-  tl::expected<std::unique_ptr<AST::Token>, Parse::Error::Token>
+  tl::expected<std::unique_ptr<AST::Token>, Parse::Error::Node>
   parse_identifier_or_keyword_token ();
-  tl::expected<std::unique_ptr<AST::TokenTree>, Parse::Error::TokenTree>
+  tl::expected<std::unique_ptr<AST::TokenTree>, Parse::Error::Node>
   parse_token_tree ();
 
   tl::expected<Parse::AttributeBody, Parse::Error::AttributeBody>
@@ -321,7 +321,7 @@ private:
   Parse::AttributeBody parse_doc_comment ();
 
   // Path-related
-  tl::expected<AST::SimplePath, Parse::Error::SimplePath> parse_simple_path ();
+  tl::expected<AST::SimplePath, Parse::Error::Node> parse_simple_path ();
   tl::expected<AST::SimplePathSegment, Parse::Error::SimplePathSegment>
   parse_simple_path_segment (int base_peek = 0);
   AST::TypePath parse_type_path ();
@@ -344,7 +344,7 @@ private:
   AST::QualifiedPathInType parse_qualified_path_in_type ();
 
   // Token tree or macro related
-  tl::expected<AST::DelimTokenTree, Parse::Error::DelimTokenTree>
+  tl::expected<AST::DelimTokenTree, Parse::Error::Node>
   parse_delim_token_tree ();
   std::unique_ptr<AST::MacroRulesDefinition>
   parse_macro_rules_def (AST::AttrVec outer_attrs);
@@ -731,10 +731,10 @@ private:
   parse_loop_label (const_TokenPtr tok);
   std::unique_ptr<AST::AsyncBlockExpr>
   parse_async_block_expr (AST::AttrVec outer_attrs = AST::AttrVec ());
-  std::unique_ptr<AST::GroupedExpr> parse_grouped_expr (AST::AttrVec 
outer_attrs
-                                                       = AST::AttrVec ());
-  std::unique_ptr<AST::ClosureExpr> parse_closure_expr (AST::AttrVec 
outer_attrs
-                                                       = AST::AttrVec ());
+  tl::expected<std::unique_ptr<AST::GroupedExpr>, Parse::Error::Node>
+  parse_grouped_expr (AST::AttrVec outer_attrs = AST::AttrVec ());
+  tl::expected<std::unique_ptr<AST::ClosureExpr>, Parse::Error::Node>
+  parse_closure_expr (AST::AttrVec outer_attrs = AST::AttrVec ());
   AST::ClosureParam parse_closure_param ();
 
   std::unique_ptr<AST::BoxExpr> parse_box_expr (AST::AttrVec outer_attrs,
-- 
2.52.0

Reply via email to