diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index f15cc3d3cba..50ba2f8cabf 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -3816,7 +3816,7 @@ DelimTokenTree::to_token_stream () const std::unique_ptr AttributeParser::parse_meta_item_lit () { - std::unique_ptr lit_expr = parser->parse_literal_expr ({}); + auto lit_expr = parser->parse_literal_expr ({}); // TODO: return nullptr instead? if (!lit_expr) @@ -3825,7 +3825,7 @@ AttributeParser::parse_meta_item_lit () lexer->peek_token ()->get_locus ())); return std::unique_ptr ( - 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 ee01f65d8a1..f3a8474db29 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 4504589040f..b70095ef30f 100644 --- a/gcc/rust/expand/rust-macro-expand.cc +++ b/gcc/rust/expand/rust-macro-expand.cc @@ -427,7 +427,7 @@ MacroExpander::match_fragment (Parser &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 f8593998527..b1592d7d300 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 e3eb201f7a1..2c305509689 100644 --- a/gcc/rust/parse/rust-parse-error.h +++ b/gcc/rust/parse/rust-parse-error.h @@ -55,22 +55,6 @@ struct Attribute Attribute (Kind kind) : kind (kind) {} }; -struct SimplePath -{ - static tl::expected make_malformed () - { - return tl::unexpected (SimplePath (Kind::MALFORMED)); - } - - enum class Kind - { - MALFORMED, - } kind; - -private: - SimplePath (Kind kind) : kind (kind) {} -}; - struct AttributeBody { static tl::expected make_invalid_path () @@ -172,45 +156,34 @@ struct AttrInput AttrInput (Kind kind) : kind (kind) {} }; -struct DelimTokenTree +struct Item { - static tl::expected - make_expected_delimiter () - { - return tl::unexpected ( - DelimTokenTree (Kind::EXPECTED_DELIMITER)); - } - - static tl::expected - make_invalid_token_tree () + static tl::expected, Item> make_end_of_file () { - return tl::unexpected ( - DelimTokenTree (Kind::INVALID_TOKEN_TREE)); + return tl::unexpected (Item (Kind::END_OF_FILE)); } - static tl::expected - make_mismatched_delimiters () + static tl::expected, Item> make_malformed () { - return tl::unexpected ( - DelimTokenTree (Kind::INVALID_TOKEN_TREE)); + return tl::unexpected (Item (Kind::MALFORMED)); } enum class Kind { - EXPECTED_DELIMITER, - INVALID_TOKEN_TREE, - MISMATCHED_DELIMITERS, + END_OF_FILE, + MALFORMED, } kind; private: - DelimTokenTree (Kind kind) : kind (kind) {} + Item (Kind kind) : kind (kind) {} }; -struct Token +struct Items { - static tl::expected, Token> make_malformed () + static tl::expected>, Items> + make_malformed (std::vector> items) { - return tl::unexpected (Token (Kind::MALFORMED)); + return tl::unexpected (Items (Kind::MALFORMED, std::move (items))); } enum class Kind @@ -218,105 +191,126 @@ struct Token MALFORMED, } kind; + Items (Items const &) = delete; + Items &operator= (Items const &) = delete; + + Items (Items &&items) = default; + Items &operator= (Items &&) = default; + + // Should we do anything with valid items ? + std::vector> items; + private: - Token (Kind kind) : kind (kind) {} + Items (Kind kind, std::vector> items) + : kind (kind), items (std::move (items)) + {} }; -struct TokenTree +struct Visibility { - static tl::expected, TokenTree> - make_malformed () + static tl::expected make_malformed () { - return tl::unexpected (TokenTree (Kind::MALFORMED)); + return tl::unexpected (Visibility (Kind::MALFORMED)); } - static tl::expected, TokenTree> - make_malformed_delimited_token_tree () + static tl::expected make_missing_path () { - return tl::unexpected ( - TokenTree (Kind::MALFORMED_DELIMITED_TOKEN_TREE)); + return tl::unexpected (Visibility (Kind::MISSING_PATH)); } enum class Kind { + MISSING_PATH, MALFORMED, - MALFORMED_DELIMITED_TOKEN_TREE, } kind; private: - TokenTree (Kind kind) : kind (kind) {} + Visibility (Kind kind) : kind (kind) {} }; -struct Item +struct LifetimeParam { - static tl::expected, Item> make_end_of_file () - { - return tl::unexpected (Item (Kind::END_OF_FILE)); - } - - static tl::expected, Item> make_malformed () + static tl::expected + make_not_a_lifetime_param () { - return tl::unexpected (Item (Kind::MALFORMED)); + return tl::unexpected ( + LifetimeParam (Kind::NOT_A_LIFETIME_PARAM)); } enum class Kind { - END_OF_FILE, - MALFORMED, + NOT_A_LIFETIME_PARAM, } kind; private: - Item (Kind kind) : kind (kind) {} + LifetimeParam (Kind kind) : kind (kind) {} }; -struct Items +class Lifetime { - static tl::expected>, Items> - make_malformed (std::vector> items) +}; + +struct LoopLabel +{ + static tl::expected make_not_loop_label () { - return tl::unexpected (Items (Kind::MALFORMED, std::move (items))); + return tl::unexpected (LoopLabel (Kind::NOT_LOOP_LABEL)); + } + + static tl::expected make_missing_colon () + { + return tl::unexpected (LoopLabel (Kind::MISSING_COLON)); } enum class Kind { - MALFORMED, + // Not an hard error + NOT_LOOP_LABEL, + // Hard error + MISSING_COLON, } kind; - Items (Items const &) = delete; - Items &operator= (Items const &) = delete; - - Items (Items &&items) = default; - Items &operator= (Items &&) = default; - - // Should we do anything with valid items ? - std::vector> items; - private: - Items (Kind kind, std::vector> items) - : kind (kind), items (std::move (items)) - {} + LoopLabel (Kind kind) : kind (kind) {} }; -struct Visibility +struct Self { - static tl::expected make_malformed () + static tl::expected, Self> + make_self_raw_pointer () { - return tl::unexpected (Visibility (Kind::MALFORMED)); + return tl::unexpected (Self (Kind::SELF_RAW_PTR)); } - static tl::expected make_missing_path () + static tl::expected, Self> make_not_self () { - return tl::unexpected (Visibility (Kind::MISSING_PATH)); + return tl::unexpected (Self (Kind::NOT_SELF)); + } + + static tl::expected, Self> make_parsing_error () + { + return tl::unexpected (Self (Kind::PARSING)); } enum class Kind { - MISSING_PATH, - MALFORMED, + SELF_RAW_PTR, + PARSING, + NOT_SELF, } kind; private: - Visibility (Kind kind) : kind (kind) {} + Self (Kind kind) : kind (kind) {} +}; + +// Generic intermediate AST node error used when the errors need no special +// handling +enum class Node +{ + // 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 bcfdd2d7a1e..97e519ec49f 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 -std::unique_ptr +tl::expected, Parse::Error::Node> Parser::parse_block_expr ( AST::AttrVec outer_attrs, tl::optional label, location_t pratt_parsed_loc) @@ -38,7 +38,7 @@ Parser::parse_block_expr ( if (!skip_token (LEFT_CURLY)) { skip_after_end_block (); - return nullptr; + return tl::unexpected (Parse::Error::Node::MALFORMED); } } @@ -55,7 +55,7 @@ Parser::parse_block_expr ( if (expr_or_stmt.is_error ()) { skip_after_end_block (); - return nullptr; + return tl::unexpected (Parse::Error::Node::CHILD_ERROR); } t = lexer.peek_token (); @@ -82,7 +82,7 @@ Parser::parse_block_expr ( add_error (std::move (error)); skip_after_end_block (); - return nullptr; + return tl::unexpected (Parse::Error::Node::MALFORMED); } // grammar allows for empty block expressions @@ -98,7 +98,7 @@ Parser::parse_block_expr ( /* Parse an anonymous const expression. This can be a regular const expression * or an underscore for deferred const inference */ template -tl::expected +tl::expected Parser::parse_anon_const () { auto current = lexer.peek_token (); @@ -111,7 +111,7 @@ Parser::parse_anon_const () auto expr = parse_expr (); if (!expr) - return tl::make_unexpected (AnonConstError::InvalidSizeExpr); + return tl::make_unexpected (Parse::Error::Node{}); return AST::AnonConst (std::move (expr), locus); } @@ -119,19 +119,20 @@ Parser::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 -std::unique_ptr +tl::expected, Parse::Error::Node> Parser::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; + return tl::unexpected (Parse::Error::Node{}); } + auto block = std::move (block_res.value ()); auto block_locus = block->get_locus (); @@ -143,7 +144,7 @@ Parser::parse_const_block_expr (AST::AttrVec outer_attrs, /* Parses a "grouped" expression (expression in parentheses), used to control * precedence. */ template -std::unique_ptr +tl::expected, Parse::Error::Node> Parser::parse_grouped_expr (AST::AttrVec outer_attrs) { location_t locus = lexer.peek_token ()->get_locus (); @@ -153,17 +154,17 @@ Parser::parse_grouped_expr (AST::AttrVec outer_attrs) // parse required expr inside parentheses std::unique_ptr 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 ( @@ -173,7 +174,7 @@ Parser::parse_grouped_expr (AST::AttrVec outer_attrs) // Parses a closure expression (closure definition). template -std::unique_ptr +tl::expected, Parse::Error::Node> Parser::parse_closure_expr (AST::AttrVec outer_attrs) { location_t locus = lexer.peek_token ()->get_locus (); @@ -233,7 +234,7 @@ Parser::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 @@ -254,12 +255,12 @@ Parser::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 - std::unique_ptr block = parse_block_expr (); - if (block == nullptr) + auto block = parse_block_expr (); + if (!block) { // error Error error (lexer.peek_token ()->get_locus (), @@ -267,11 +268,12 @@ Parser::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 ( - 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))); } @@ -288,7 +290,7 @@ Parser::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 ( @@ -299,7 +301,7 @@ Parser::parse_closure_expr (AST::AttrVec outer_attrs) // Parses a literal token (to literal expression). template -std::unique_ptr +tl::expected, Parse::Error::Node> Parser::parse_literal_expr (AST::AttrVec outer_attrs) { // TODO: change if literal representation in lexer changes @@ -365,7 +367,7 @@ Parser::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 @@ -433,7 +435,7 @@ Parser::parse_try_expr (AST::AttrVec outer_attrs, skip_token (TRY); } - std::unique_ptr block_expr = parse_block_expr (); + auto block_expr = parse_block_expr (); if (!block_expr) { @@ -445,7 +447,8 @@ Parser::parse_try_expr (AST::AttrVec outer_attrs, } return std::unique_ptr ( - 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::parse_if_expr (AST::AttrVec outer_attrs, } // parse required block expr - std::unique_ptr 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::parse_if_expr (AST::AttrVec outer_attrs, { // single selection - end of if expression return std::unique_ptr ( - 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::parse_if_expr (AST::AttrVec outer_attrs, { // double selection - else // parse else block expr (required) - std::unique_ptr 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::parse_if_expr (AST::AttrVec outer_attrs, return std::unique_ptr ( 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::parse_if_expr (AST::AttrVec outer_attrs, return std::unique_ptr ( 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::parse_if_expr (AST::AttrVec outer_attrs, return std::unique_ptr ( 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::parse_if_let_expr (AST::AttrVec outer_attrs, * expression here? or actually probably in semantic analysis. */ // parse block expression (required) - std::unique_ptr 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::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 ( - new AST::IfLetExpr (std::move (match_arm_patterns), - std::move (scrutinee_expr), std::move (if_let_body), - std::move (outer_attrs), locus)); + return std::unique_ptr (new AST::IfLetExpr ( + std::move (match_arm_patterns), std::move (scrutinee_expr), + std::move (if_let_body.value ()), std::move (outer_attrs), locus)); } else { @@ -759,8 +761,8 @@ Parser::parse_if_let_expr (AST::AttrVec outer_attrs, { // double selection - else // parse else block expr (required) - std::unique_ptr 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::parse_if_let_expr (AST::AttrVec outer_attrs, return std::unique_ptr ( new AST::IfLetExprConseqElse (std::move (match_arm_patterns), 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::parse_if_let_expr (AST::AttrVec outer_attrs, return std::unique_ptr ( new AST::IfLetExprConseqElse ( std::move (match_arm_patterns), 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::parse_if_let_expr (AST::AttrVec outer_attrs, return std::unique_ptr ( new AST::IfLetExprConseqElse ( std::move (match_arm_patterns), 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::parse_loop_expr (AST::AttrVec outer_attrs, } // parse loop body, which is required - std::unique_ptr loop_body = parse_block_expr (); - if (loop_body == nullptr) + auto loop_body = parse_block_expr (); + if (!loop_body) return nullptr; return std::unique_ptr ( - 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::parse_while_loop_expr ( * semantic analysis */ // parse loop body (required) - std::unique_ptr 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::parse_while_loop_expr ( } return std::unique_ptr ( - 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::parse_while_let_loop_expr ( * semantic analysis. */ // parse loop body, which is required - std::unique_ptr 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::parse_while_let_loop_expr ( return nullptr; } - return std::unique_ptr (new AST::WhileLetLoopExpr ( - std::move (predicate_patterns), std::move (predicate_expr), - std::move (body), locus, std::move (label), std::move (outer_attrs))); + return std::unique_ptr ( + new AST::WhileLetLoopExpr (std::move (predicate_patterns), + 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::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 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::parse_for_loop_expr ( // skip somewhere? return nullptr; } - return std::unique_ptr ( 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))); } @@ -1106,33 +1109,34 @@ std::unique_ptr Parser::parse_labelled_loop_expr (const_TokenPtr tok, AST::AttrVec outer_attrs) { - /* TODO: decide whether it should not work if there is no label, or parse it - * with no label at the moment, I will make it not work with no label - * because that's the implication. */ - - if (tok->get_id () != LIFETIME) - { - Error error (tok->get_locus (), - "expected lifetime in labelled loop expr (to parse loop " - "label) - found %qs", - tok->get_token_description ()); - add_error (std::move (error)); - - // skip? - return nullptr; - } - // parse loop label (required) - // TODO: Convert this return type to tl::expected instead of tl::optional auto parsed_label = parse_loop_label (tok); if (!parsed_label) { - Error error (lexer.peek_token ()->get_locus (), - "failed to parse loop label in labelled loop expr"); - add_error (std::move (error)); + /* TODO: decide whether it should not work if there is no label, or parse + * it with no label at the moment, I will make it not work with no label + * because that's the implication. */ - // skip? - return nullptr; + if (parsed_label.error ().kind + == Parse::Error::LoopLabel::Kind::NOT_LOOP_LABEL) + { + Error error (tok->get_locus (), + "expected lifetime in labelled loop expr (to parse loop " + "label) - found %qs", + tok->get_token_description ()); + add_error (std::move (error)); + return nullptr; + } + + else + { + Error error (lexer.peek_token ()->get_locus (), + "failed to parse loop label in labelled loop expr"); + add_error (std::move (error)); + + // skip? + return nullptr; + } } auto label = parsed_label @@ -1160,7 +1164,14 @@ Parser::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 (), @@ -1315,8 +1326,8 @@ Parser::parse_async_block_expr (AST::AttrVec outer_attrs) } // parse block expression (required) - std::unique_ptr 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 (), @@ -1328,7 +1339,7 @@ Parser::parse_async_block_expr (AST::AttrVec outer_attrs) } return std::unique_ptr ( - new AST::AsyncBlockExpr (std::move (block_expr), has_move, + new AST::AsyncBlockExpr (std::move (block_expr.value ()), has_move, std::move (outer_attrs), locus)); } @@ -1346,8 +1357,8 @@ Parser::parse_unsafe_block_expr ( } // parse block expression (required) - std::unique_ptr 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 (), @@ -1357,10 +1368,9 @@ Parser::parse_unsafe_block_expr ( // skip somewhere? return nullptr; } - return std::unique_ptr ( - 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. @@ -2203,8 +2213,14 @@ Parser::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) @@ -2252,8 +2268,14 @@ Parser::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 (), @@ -4064,8 +4086,8 @@ Parser::parse_closure_expr_pratt (const_TokenPtr tok, } // parse block expr, which is required - std::unique_ptr block = parse_block_expr (); - if (block == nullptr) + auto block = parse_block_expr (); + if (!block) { // error Error error (lexer.peek_token ()->get_locus (), @@ -4077,7 +4099,8 @@ Parser::parse_closure_expr_pratt (const_TokenPtr tok, } return std::unique_ptr ( - 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-path.hxx b/gcc/rust/parse/rust-parse-impl-path.hxx index 41b220e49a7..bb9a91ac384 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 -tl::expected +tl::expected Parser::parse_simple_path () { bool has_opening_scope_resolution = false; @@ -37,7 +37,7 @@ Parser::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::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::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 bb8d9aa1851..bd0c07b63ef 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 -tl::expected, Parse::Error::TokenTree> +tl::expected, Parse::Error::Node> Parser::parse_token_tree () { const_TokenPtr t = lexer.peek_token (); @@ -43,8 +43,7 @@ Parser::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 ( @@ -62,7 +61,7 @@ Parser::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::parse_token_tree () // Parses a delimited token tree template -tl::expected +tl::expected Parser::parse_delim_token_tree () { const_TokenPtr t = lexer.peek_token (); @@ -100,7 +99,7 @@ Parser::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::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::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 4ad4f834336..abfcb5c4c5f 100644 --- a/gcc/rust/parse/rust-parse-impl.hxx +++ b/gcc/rust/parse/rust-parse-impl.hxx @@ -314,7 +314,7 @@ Parser::parse_crate () // Parses an identifier/keyword as a Token template -tl::expected, Parse::Error::Token> +tl::expected, Parse::Error::Node> Parser::parse_identifier_or_keyword_token () { const_TokenPtr t = lexer.peek_token (); @@ -327,7 +327,7 @@ Parser::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); } } @@ -1588,7 +1588,7 @@ Parser::parse_function (AST::Visibility vis, auto initial_param = parse_self_param (); if (!initial_param.has_value () - && initial_param.error () != ParseSelfError::NOT_SELF) + && initial_param.error ().kind != Parse::Error::Self::Kind::NOT_SELF) return nullptr; if (initial_param.has_value () && lexer.peek_token ()->get_id () == COMMA) @@ -1627,10 +1627,10 @@ Parser::parse_function (AST::Visibility vis, lexer.skip_token (); else { - std::unique_ptr 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 ( @@ -1749,9 +1749,10 @@ Parser::parse_generic_param (EndTokenPred is_end_token) auto lifetime = parse_lifetime (false); if (!lifetime) { - rust_error_at ( - token->get_locus (), - "failed to parse lifetime in generic parameter list"); + Error error (token->get_locus (), + "failed to parse lifetime in generic parameter list"); + add_error (std::move (error)); + return nullptr; } @@ -1794,9 +1795,11 @@ Parser::parse_generic_param (EndTokenPred is_end_token) type = parse_type (); if (!type) { - rust_error_at ( + Error error ( lexer.peek_token ()->get_locus (), "failed to parse type in type param in generic params"); + add_error (std::move (error)); + return nullptr; } } @@ -1830,11 +1833,13 @@ Parser::parse_generic_param (EndTokenPred is_end_token) if (!default_expr) { - rust_error_at (tok->get_locus (), - "invalid token for start of default value for " - "const generic parameter: expected %, " - "% or %, got %qs", - token_id_to_str (tok->get_id ())); + Error error (tok->get_locus (), + "invalid token for start of default value for " + "const generic parameter: expected %, " + "% or %, got %qs", + token_id_to_str (tok->get_id ())); + + add_error (std::move (error)); return nullptr; } @@ -1854,9 +1859,11 @@ Parser::parse_generic_param (EndTokenPred is_end_token) } default: // FIXME: Can we clean this last call with a method call? - rust_error_at (token->get_locus (), - "unexpected token when parsing generic parameters: %qs", - token->as_string ().c_str ()); + Error error (token->get_locus (), + "unexpected token when parsing generic parameters: %qs", + token->as_string ().c_str ()); + add_error (std::move (error)); + return nullptr; } @@ -2138,7 +2145,7 @@ Parser::parse_non_ptr_sequence ( /* Parses a single lifetime generic parameter (not including comma). */ template -tl::expected +tl::expected Parser::parse_lifetime_param () { // parse outer attributes, which are optional and may not exist @@ -2149,7 +2156,7 @@ Parser::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 ({}); + return Parse::Error::LifetimeParam::make_not_a_lifetime_param (); } lexer.skip_token (); AST::Lifetime lifetime (AST::Lifetime::NAMED, lifetime_tok->get_str (), @@ -2827,7 +2834,7 @@ Parser::parse_lifetime_bounds (EndTokenPred is_end_token) /* Parses a lifetime token (named, 'static, or '_). Also handles lifetime not * existing. */ template -tl::expected +tl::expected Parser::parse_lifetime (bool allow_elided) { const_TokenPtr lifetime_tok = lexer.peek_token (); @@ -2839,7 +2846,7 @@ Parser::parse_lifetime (bool allow_elided) } else { - return tl::make_unexpected ({}); + return tl::make_unexpected ({}); } } lexer.skip_token (); @@ -4286,7 +4293,7 @@ Parser::parse_inherent_impl_function_or_method ( auto initial_param = parse_self_param (); if (!initial_param.has_value () - && initial_param.error () != ParseSelfError::NOT_SELF) + && initial_param.error ().kind != Parse::Error::Self::Kind::NOT_SELF) return nullptr; /* FIXME: ensure that self param doesn't accidently consume tokens for a @@ -4331,7 +4338,7 @@ Parser::parse_inherent_impl_function_or_method ( { auto result = parse_block_expr (); - if (result == nullptr) + if (!result) { Error error ( lexer.peek_token ()->get_locus (), @@ -4342,7 +4349,7 @@ Parser::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 ( @@ -4487,7 +4494,7 @@ Parser::parse_trait_impl_function_or_method ( auto initial_param = parse_self_param (); if (!initial_param.has_value () - && initial_param.error () != ParseSelfError::NOT_SELF) + && initial_param.error ().kind != Parse::Error::Self::Kind::NOT_SELF) return nullptr; // FIXME: ensure that self param doesn't accidently consume tokens for a @@ -4569,7 +4576,7 @@ Parser::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", @@ -4579,7 +4586,7 @@ Parser::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 ( @@ -4883,7 +4890,13 @@ Parser::parse_let_stmt (AST::AttrVec outer_attrs, tl::optional> 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) { @@ -4949,7 +4962,13 @@ Parser::parse_generic_arg () tok->get_locus ()); } case LEFT_CURLY: - expr = parse_block_expr (); + { + auto res = parse_block_expr (); + if (res) + expr = std::move (res.value ()); + else + return tl::nullopt; + } break; case MINUS: case STRING_LITERAL: @@ -4958,7 +4977,13 @@ Parser::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 @@ -5132,7 +5157,7 @@ Parser::parse_generic_args_binding () // Parses a self param. Also handles self param not existing. template -tl::expected, ParseSelfError> +tl::expected, Parse::Error::Self> Parser::parse_self_param () { bool has_reference = false; @@ -5154,9 +5179,10 @@ Parser::parse_self_param () break; if (i == s.size ()) { - rust_error_at (lexer.peek_token ()->get_locus (), - "cannot pass % by raw pointer"); - return tl::make_unexpected (ParseSelfError::SELF_PTR); + Error error (lexer.peek_token ()->get_locus (), + "cannot pass % by raw pointer"); + add_error (std::move (error)); + return Parse::Error::Self::make_self_raw_pointer (); } } @@ -5177,7 +5203,7 @@ Parser::parse_self_param () is_self = true; if (!is_self) - return tl::make_unexpected (ParseSelfError::NOT_SELF); + return Parse::Error::Self::make_not_self (); // test if self is a reference parameter if (lexer.peek_token ()->get_id () == AMP) @@ -5200,7 +5226,7 @@ Parser::parse_self_param () add_error (std::move (error)); // skip after somewhere? - return tl::make_unexpected (ParseSelfError::PARSING); + return Parse::Error::Self::make_parsing_error (); } } } @@ -5218,7 +5244,7 @@ Parser::parse_self_param () if (self_tok->get_id () != SELF) { // skip after somewhere? - return tl::make_unexpected (ParseSelfError::NOT_SELF); + return Parse::Error::Self::make_not_self (); } lexer.skip_token (); @@ -5237,12 +5263,12 @@ Parser::parse_self_param () add_error (std::move (error)); // skip after somewhere? - return tl::make_unexpected (ParseSelfError::PARSING); + return Parse::Error::Self::make_parsing_error (); } } // ensure that cannot have both type and reference - if (type != nullptr && has_reference) + if (type && has_reference) { Error error ( lexer.peek_token ()->get_locus (), @@ -5250,7 +5276,7 @@ Parser::parse_self_param () add_error (std::move (error)); // skip after somewhere? - return tl::make_unexpected (ParseSelfError::PARSING); + return Parse::Error::Self::make_parsing_error (); } if (has_reference) @@ -5379,15 +5405,14 @@ Parser::parse_expr_stmt (AST::AttrVec outer_attrs, // Parses a loop label used in loop expressions. template -tl::expected +tl::expected Parser::parse_loop_label (const_TokenPtr tok) { // parse lifetime - if doesn't exist, assume no label if (tok->get_id () != LIFETIME) { // not necessarily an error - return tl::unexpected ( - ParseLoopLabelError::NOT_LOOP_LABEL); + return Parse::Error::LoopLabel::make_not_loop_label (); } /* FIXME: check for named lifetime requirement here? or check in semantic * analysis phase? */ @@ -5396,11 +5421,10 @@ Parser::parse_loop_label (const_TokenPtr tok) if (!skip_token (COLON)) { // skip somewhere? - return tl::unexpected ( - ParseLoopLabelError::MISSING_COLON); + Parse::Error::LoopLabel::make_missing_colon (); } - return tl::expected ( + return tl::expected ( AST::LoopLabel (std::move (label), tok->get_locus ())); } diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 27c8185433b..547c093e16e 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -29,32 +29,6 @@ along with GCC; see the file COPYING3. If not see namespace Rust { -class ParseLifetimeParamError -{ -}; - -class ParseLifetimeError -{ -}; - -enum class AnonConstError -{ - InvalidSizeExpr, -}; - -enum class ParseLoopLabelError -{ - NOT_LOOP_LABEL, - MISSING_COLON, -}; - -enum class ParseSelfError -{ - SELF_PTR, - PARSING, - NOT_SELF, -}; - // Left binding powers of operations. enum binding_powers { @@ -267,17 +241,17 @@ template class Parser parse_expr (AST::AttrVec outer_attrs = AST::AttrVec (), ParseRestrictions restrictions = ParseRestrictions ()); - std::unique_ptr parse_literal_expr (AST::AttrVec outer_attrs - = AST::AttrVec ()); + tl::expected, Parse::Error::Node> + parse_literal_expr (AST::AttrVec outer_attrs = AST::AttrVec ()); - std::unique_ptr + tl::expected, Parse::Error::Node> parse_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (), tl::optional = tl::nullopt, location_t pratt_parsed_loc = UNKNOWN_LOCATION); - tl::expected parse_anon_const (); + tl::expected parse_anon_const (); - std::unique_ptr + tl::expected, Parse::Error::Node> parse_const_block_expr (AST::AttrVec outer_attrs = AST::AttrVec (), location_t loc = UNKNOWN_LOCATION); @@ -307,9 +281,9 @@ template class Parser std::vector> parse_lifetime_params (); tl::expected parse_visibility (); std::unique_ptr parse_identifier_pattern (); - tl::expected, Parse::Error::Token> + tl::expected, Parse::Error::Node> parse_identifier_or_keyword_token (); - tl::expected, Parse::Error::TokenTree> + tl::expected, Parse::Error::Node> parse_token_tree (); tl::expected @@ -347,7 +321,7 @@ template class Parser Parse::AttributeBody parse_doc_comment (); // Path-related - tl::expected parse_simple_path (); + tl::expected parse_simple_path (); tl::expected parse_simple_path_segment (int base_peek = 0); AST::TypePath parse_type_path (); @@ -370,7 +344,7 @@ template class Parser AST::QualifiedPathInType parse_qualified_path_in_type (); // Token tree or macro related - tl::expected + tl::expected parse_delim_token_tree (); std::unique_ptr parse_macro_rules_def (AST::AttrVec outer_attrs); @@ -420,7 +394,7 @@ template class Parser ParseFunction parsing_function, EndTokenPred is_end_token, std::string error_msg = "failed to parse generic param in generic params") -> std::vector; - tl::expected + tl::expected parse_lifetime_param (); std::vector> parse_type_params (); template @@ -450,7 +424,7 @@ template class Parser std::vector parse_lifetime_bounds (); template std::vector parse_lifetime_bounds (EndTokenPred is_end_token); - tl::expected + tl::expected parse_lifetime (bool allow_elided); AST::Lifetime lifetime_from_token (const_TokenPtr tok); std::unique_ptr @@ -486,7 +460,8 @@ template class Parser std::unique_ptr parse_trait_const (AST::AttrVec outer_attrs); - tl::expected, ParseSelfError> parse_self_param (); + tl::expected, Parse::Error::Self> + parse_self_param (); std::unique_ptr parse_impl (AST::Visibility vis, AST::AttrVec outer_attrs); @@ -753,14 +728,14 @@ template class Parser std::unique_ptr parse_labelled_loop_expr (const_TokenPtr tok, AST::AttrVec outer_attrs = AST::AttrVec ()); - tl::expected + tl::expected parse_loop_label (const_TokenPtr tok); std::unique_ptr parse_async_block_expr (AST::AttrVec outer_attrs = AST::AttrVec ()); - std::unique_ptr parse_grouped_expr (AST::AttrVec outer_attrs - = AST::AttrVec ()); - std::unique_ptr parse_closure_expr (AST::AttrVec outer_attrs - = AST::AttrVec ()); + tl::expected, Parse::Error::Node> + parse_grouped_expr (AST::AttrVec outer_attrs = AST::AttrVec ()); + tl::expected, Parse::Error::Node> + parse_closure_expr (AST::AttrVec outer_attrs = AST::AttrVec ()); AST::ClosureParam parse_closure_param (); std::unique_ptr parse_box_expr (AST::AttrVec outer_attrs,