From: Pierre-Emmanuel Patry <[email protected]>
gcc/rust/ChangeLog:
* parse/rust-parse-error.h (struct EnumVariant): Add error for enum
variant.
* parse/rust-parse-impl.hxx: Use new error type instead of nullptr.
* parse/rust-parse.h: Update function prototype.
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/488a47ff11607dda54df1b6ec112f1f9b8f9ee9a
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4450
gcc/rust/parse/rust-parse-error.h | 42 +++++++++++++++++++++++
gcc/rust/parse/rust-parse-impl.hxx | 55 +++++++++++++++---------------
gcc/rust/parse/rust-parse.h | 3 +-
3 files changed, 71 insertions(+), 29 deletions(-)
diff --git a/gcc/rust/parse/rust-parse-error.h
b/gcc/rust/parse/rust-parse-error.h
index 73d42f0c0..46ac46245 100644
--- a/gcc/rust/parse/rust-parse-error.h
+++ b/gcc/rust/parse/rust-parse-error.h
@@ -27,6 +27,48 @@ namespace Rust {
namespace Parse {
namespace Error {
+struct EnumVariant
+{
+ enum class Kind
+ {
+ CHILD_ERROR,
+ NO_IDENTIFIER,
+ UNFINISHED_TUPLE_VARIANT,
+ } kind;
+
+ static tl::expected<std::unique_ptr<AST::EnumItem>, EnumVariant>
+ make_not_identifier (const_TokenPtr unexpected_token)
+ {
+ return tl::unexpected<EnumVariant> (EnumVariant (unexpected_token));
+ }
+
+ static tl::expected<std::unique_ptr<AST::EnumItem>, EnumVariant>
+ make_child_error ()
+ {
+ return tl::unexpected<EnumVariant> (EnumVariant (Kind::CHILD_ERROR));
+ }
+
+ static tl::expected<std::unique_ptr<AST::EnumItem>, EnumVariant>
+ make_unfinished_tuple_variant ()
+ {
+ return tl::unexpected<EnumVariant> (
+ EnumVariant (Kind::UNFINISHED_TUPLE_VARIANT));
+ }
+
+private:
+ EnumVariant (const_TokenPtr unexpected_token)
+ : kind (Kind::NO_IDENTIFIER), unexpected_token (unexpected_token)
+ {}
+
+ EnumVariant (Kind kind) : kind (kind), unexpected_token (nullptr)
+ {
+ rust_assert (kind != Kind::NO_IDENTIFIER);
+ }
+
+ // Only valid for missing identifier
+ const_TokenPtr unexpected_token;
+};
+
struct Attribute
{
static tl::expected<AST::Attribute, Attribute> make_malformed ()
diff --git a/gcc/rust/parse/rust-parse-impl.hxx
b/gcc/rust/parse/rust-parse-impl.hxx
index bfa545b7c..9ed5eef15 100644
--- a/gcc/rust/parse/rust-parse-impl.hxx
+++ b/gcc/rust/parse/rust-parse-impl.hxx
@@ -2750,7 +2750,7 @@ Parser<ManagedTokenSource>::parse_trait_bound ()
// handle TypePath
AST::TypePath type_path = parse_type_path ();
- if (type_path.is_error())
+ if (type_path.is_error ())
return nullptr;
// handle closing parentheses
@@ -3353,26 +3353,26 @@ Parser<ManagedTokenSource>::parse_enum_items ()
{
std::vector<std::unique_ptr<AST::EnumItem>> items;
- std::unique_ptr<AST::EnumItem> initial_item = parse_enum_item ();
+ auto initial_item = parse_enum_item ();
// Return empty item list if no field there
- if (initial_item == nullptr)
+ if (!initial_item)
return items;
- items.push_back (std::move (initial_item));
+ items.push_back (std::move (initial_item.value ()));
while (lexer.peek_token ()->get_id () == COMMA)
{
lexer.skip_token ();
- std::unique_ptr<AST::EnumItem> item = parse_enum_item ();
- if (item == nullptr)
+ auto item = parse_enum_item ();
+ if (!item)
{
// this would occur with a trailing comma, which is allowed
break;
}
- items.push_back (std::move (item));
+ items.push_back (std::move (item.value ()));
}
items.shrink_to_fit ();
@@ -3389,13 +3389,13 @@ Parser<ManagedTokenSource>::parse_enum_items
(EndTokenPred is_end_tok)
{
std::vector<std::unique_ptr<AST::EnumItem>> items;
- std::unique_ptr<AST::EnumItem> initial_item = parse_enum_item ();
+ auto initial_item = parse_enum_item ();
// Return empty item list if no field there
- if (initial_item == nullptr)
+ if (!initial_item)
return items;
- items.push_back (std::move (initial_item));
+ items.push_back (std::move (initial_item.value ()));
while (lexer.peek_token ()->get_id () == COMMA)
{
@@ -3404,8 +3404,8 @@ Parser<ManagedTokenSource>::parse_enum_items
(EndTokenPred is_end_tok)
if (is_end_tok (lexer.peek_token ()->get_id ()))
break;
- std::unique_ptr<AST::EnumItem> item = parse_enum_item ();
- if (item == nullptr)
+ auto item = parse_enum_item ();
+ if (!item)
{
/* TODO should this ignore all successfully parsed enum items just
* because one failed? */
@@ -3416,7 +3416,7 @@ Parser<ManagedTokenSource>::parse_enum_items
(EndTokenPred is_end_tok)
return {};
}
- items.push_back (std::move (item));
+ items.push_back (std::move (item.value ()));
}
items.shrink_to_fit ();
@@ -3428,7 +3428,7 @@ Parser<ManagedTokenSource>::parse_enum_items
(EndTokenPred is_end_tok)
/* Parses a single enum variant item in an enum definition. Does not parse
* commas. */
template <typename ManagedTokenSource>
-std::unique_ptr<AST::EnumItem>
+tl::expected<std::unique_ptr<AST::EnumItem>, Parse::Error::EnumVariant>
Parser<ManagedTokenSource>::parse_enum_item ()
{
// parse outer attributes if they exist
@@ -3437,7 +3437,7 @@ Parser<ManagedTokenSource>::parse_enum_item ()
// parse visibility, which may or may not exist
auto vis_res = parse_visibility ();
if (!vis_res)
- return nullptr;
+ return Parse::Error::EnumVariant::make_child_error ();
auto vis = vis_res.value ();
// parse name for enum item, which is required
@@ -3445,7 +3445,7 @@ Parser<ManagedTokenSource>::parse_enum_item ()
if (item_name_tok->get_id () != IDENTIFIER)
{
// this may not be an error but it means there is no enum item here
- return nullptr;
+ return Parse::Error::EnumVariant::make_not_identifier (item_name_tok);
}
lexer.skip_token ();
Identifier item_name{item_name_tok};
@@ -3469,7 +3469,7 @@ Parser<ManagedTokenSource>::parse_enum_item ()
if (!skip_token (RIGHT_PAREN))
{
// skip after somewhere
- return nullptr;
+ return Parse::Error::EnumVariant::make_unfinished_tuple_variant ();
}
return std::unique_ptr<AST::EnumItemTuple> (new AST::EnumItemTuple (
@@ -3487,7 +3487,7 @@ Parser<ManagedTokenSource>::parse_enum_item ()
if (!skip_token (RIGHT_CURLY))
{
// skip after somewhere
- return nullptr;
+ return Parse::Error::EnumVariant::make_unfinished_tuple_variant ();
}
return std::unique_ptr<AST::EnumItemStruct> (new AST::EnumItemStruct (
@@ -3501,20 +3501,19 @@ Parser<ManagedTokenSource>::parse_enum_item ()
auto discriminant_expr = parse_expr ();
if (!discriminant_expr)
- return nullptr;
+ return Parse::Error::EnumVariant::make_child_error ();
- return std::unique_ptr<AST::EnumItemDiscriminant> (
- new AST::EnumItemDiscriminant (std::move (item_name), std::move (vis),
- std::move (discriminant_expr.value ()),
- std::move (outer_attrs),
- item_name_tok->get_locus ()));
+ return std::make_unique<AST::EnumItemDiscriminant> (
+ std::move (item_name), std::move (vis),
+ std::move (discriminant_expr.value ()), std::move (outer_attrs),
+ item_name_tok->get_locus ());
}
default:
// regular enum with just an identifier
- return std::unique_ptr<AST::EnumItem> (
- new AST::EnumItem (std::move (item_name), std::move (vis),
- std::move (outer_attrs),
- item_name_tok->get_locus ()));
+ return std::make_unique<AST::EnumItem> (std::move (item_name),
+ std::move (vis),
+ std::move (outer_attrs),
+ item_name_tok->get_locus ());
}
}
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 289018e32..96b2d091f 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -438,7 +438,8 @@ private:
template <typename EndTokenPred>
std::vector<std::unique_ptr<AST::EnumItem>>
parse_enum_items (EndTokenPred is_end_token);
- std::unique_ptr<AST::EnumItem> parse_enum_item ();
+ tl::expected<std::unique_ptr<AST::EnumItem>, Parse::Error::EnumVariant>
+ parse_enum_item ();
std::unique_ptr<AST::Union> parse_union (AST::Visibility vis,
AST::AttrVec outer_attrs);
std::unique_ptr<AST::ConstantItem>
--
2.53.0