diff options
author | Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com> | 2023-11-15 13:02:28 +0100 |
---|---|---|
committer | P-E-P <32375388+P-E-P@users.noreply.github.com> | 2023-11-21 09:19:08 +0000 |
commit | d2f2f68a8d9d3ce71e97fb586318445d7e7cd984 (patch) | |
tree | 4e5c221a7f334bf8ce49554925cf3303fe28b967 | |
parent | 6f8b0ffd7667c81af7798c5c02eb24f7b2a79bd5 (diff) | |
download | gcc-d2f2f68a8d9d3ce71e97fb586318445d7e7cd984.zip gcc-d2f2f68a8d9d3ce71e97fb586318445d7e7cd984.tar.gz gcc-d2f2f68a8d9d3ce71e97fb586318445d7e7cd984.tar.bz2 |
Report self parameter parsing error kind
Self parameter parsing errors may come from different situations, which
should not be handled in the same way. It is now possible to
differentiate a missing self parameter from a self pointer or a parsing
error.
gcc/rust/ChangeLog:
* parse/rust-parse-impl.h (Parser::parse_function): Early return on
unrecoverable errors.
(Parser::parse_trait_item): Likewise.
(Parser::parse_self_param): Update return type.
* parse/rust-parse.h (enum ParseSelfError): Add enumeration to describe
different self parameter parsing errors.
Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.patry@embecosm.com>
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 72 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse.h | 12 |
2 files changed, 56 insertions, 28 deletions
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index eb52782..5a276d1 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -2880,8 +2880,13 @@ Parser<ManagedTokenSource>::parse_function (AST::Visibility vis, return nullptr; } - std::unique_ptr<AST::Param> initial_param = parse_self_param (); - if (initial_param != nullptr) + auto initial_param = parse_self_param (); + + if (!initial_param.has_value () + && initial_param.error () != ParseSelfError::NOT_SELF) + return nullptr; + + if (initial_param.has_value ()) skip_token (COMMA); // parse function parameters (only if next token isn't right paren) @@ -2891,9 +2896,9 @@ Parser<ManagedTokenSource>::parse_function (AST::Visibility vis, function_params = parse_function_params ([] (TokenId id) { return id == RIGHT_PAREN; }); - if (initial_param != nullptr) + if (initial_param.has_value ()) function_params.insert (function_params.begin (), - std::move (initial_param)); + std::move (*initial_param)); if (!skip_token (RIGHT_PAREN)) { @@ -5063,13 +5068,15 @@ Parser<ManagedTokenSource>::parse_trait_item () /* now for function vs method disambiguation - method has opening * "self" param */ - std::unique_ptr<AST::Param> initial_param = parse_self_param (); + auto initial_param = parse_self_param (); + if (!initial_param.has_value () && initial_param.error () != NOT_SELF) + return nullptr; /* FIXME: ensure that self param doesn't accidently consume tokens for * a function */ bool is_method = false; - if (initial_param != nullptr) + if (initial_param.has_value ()) { - if (initial_param->is_self ()) + if ((*initial_param)->is_self ()) is_method = true; /* skip comma so function and method regular params can be parsed @@ -5089,9 +5096,9 @@ Parser<ManagedTokenSource>::parse_trait_item () return nullptr; } - if (initial_param != nullptr) + if (initial_param.has_value ()) function_params.insert (function_params.begin (), - std::move (initial_param)); + std::move (*initial_param)); // parse return type (optional) std::unique_ptr<AST::Type> return_type = parse_function_return_type (); @@ -5609,14 +5616,18 @@ Parser<ManagedTokenSource>::parse_inherent_impl_function_or_method ( // now for function vs method disambiguation - method has opening "self" // param - std::unique_ptr<AST::Param> initial_param = parse_self_param (); + auto initial_param = parse_self_param (); + + if (!initial_param.has_value () && initial_param.error () != NOT_SELF) + return nullptr; + /* FIXME: ensure that self param doesn't accidently consume tokens for a * function one idea is to lookahead up to 4 tokens to see whether self is * one of them */ bool is_method = false; - if (initial_param != nullptr) + if (initial_param.has_value ()) { - if (initial_param->is_self ()) + if ((*initial_param)->is_self ()) is_method = true; /* skip comma so function and method regular params can be parsed in @@ -5629,9 +5640,9 @@ Parser<ManagedTokenSource>::parse_inherent_impl_function_or_method ( std::vector<std::unique_ptr<AST::Param>> function_params = parse_function_params ([] (TokenId id) { return id == RIGHT_PAREN; }); - if (initial_param != nullptr) + if (initial_param.has_value ()) function_params.insert (function_params.begin (), - std::move (initial_param)); + std::move (*initial_param)); if (!skip_token (RIGHT_PAREN)) { @@ -5817,13 +5828,17 @@ Parser<ManagedTokenSource>::parse_trait_impl_function_or_method ( // now for function vs method disambiguation - method has opening "self" // param - std::unique_ptr<AST::Param> initial_param = parse_self_param (); + auto initial_param = parse_self_param (); + + if (!initial_param.has_value () && initial_param.error () != NOT_SELF) + return nullptr; + // FIXME: ensure that self param doesn't accidently consume tokens for a // function bool is_method = false; - if (initial_param != nullptr) + if (initial_param.has_value ()) { - if (initial_param->is_self ()) + if ((*initial_param)->is_self ()) is_method = true; // skip comma so function and method regular params can be parsed in @@ -5861,9 +5876,9 @@ Parser<ManagedTokenSource>::parse_trait_impl_function_or_method ( } } - if (initial_param != nullptr) + if (initial_param.has_value ()) function_params.insert (function_params.begin (), - std::move (initial_param)); + std::move (*initial_param)); // DEBUG rust_debug ("successfully parsed function params in function or method " @@ -7112,7 +7127,7 @@ Parser<ManagedTokenSource>::parse_qualified_path_in_type () // Parses a self param. Also handles self param not existing. template <typename ManagedTokenSource> -std::unique_ptr<AST::Param> +tl::expected<std::unique_ptr<AST::Param>, ParseSelfError> Parser<ManagedTokenSource>::parse_self_param () { bool has_reference = false; @@ -7133,8 +7148,11 @@ Parser<ManagedTokenSource>::parse_self_param () if (lexer.peek_token (i)->get_id () != s[i]) break; if (i == s.size ()) - rust_error_at (lexer.peek_token ()->get_locus (), - "cannot pass %<self%> by raw pointer"); + { + rust_error_at (lexer.peek_token ()->get_locus (), + "cannot pass %<self%> by raw pointer"); + return tl::make_unexpected (ParseSelfError::SELF_PTR); + } } // Trying to find those patterns: @@ -7154,7 +7172,7 @@ Parser<ManagedTokenSource>::parse_self_param () is_self = true; if (!is_self) - return nullptr; + return tl::make_unexpected (ParseSelfError::NOT_SELF); // test if self is a reference parameter if (lexer.peek_token ()->get_id () == AMP) @@ -7175,7 +7193,7 @@ Parser<ManagedTokenSource>::parse_self_param () add_error (std::move (error)); // skip after somewhere? - return nullptr; + return tl::make_unexpected (ParseSelfError::PARSING); } } } @@ -7193,7 +7211,7 @@ Parser<ManagedTokenSource>::parse_self_param () if (self_tok->get_id () != SELF) { // skip after somewhere? - return nullptr; + return tl::make_unexpected (ParseSelfError::NOT_SELF); } lexer.skip_token (); @@ -7212,7 +7230,7 @@ Parser<ManagedTokenSource>::parse_self_param () add_error (std::move (error)); // skip after somewhere? - return nullptr; + return tl::make_unexpected (ParseSelfError::PARSING); } } @@ -7225,7 +7243,7 @@ Parser<ManagedTokenSource>::parse_self_param () add_error (std::move (error)); // skip after somewhere? - return nullptr; + return tl::make_unexpected (ParseSelfError::PARSING); } if (has_reference) diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 08e6ce0..e873d52 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -22,6 +22,8 @@ along with GCC; see the file COPYING3. If not see #include "rust-ast-full.h" #include "rust-diagnostics.h" +#include "expected.h" + namespace Rust { /* HACK: used to resolve the expression-or-statement problem at the end of a * block by allowing either to be returned (technically). Tagged union would @@ -93,6 +95,12 @@ struct ParseRestrictions bool allow_close_after_expr_stmt = false; }; +enum ParseSelfError +{ + SELF_PTR, + PARSING, + NOT_SELF, +}; // Parser implementation for gccrs. // TODO: if updated to C++20, ManagedTokenSource would be useful as a concept template <typename ManagedTokenSource> class Parser @@ -335,7 +343,9 @@ private: parse_trait_type (AST::AttrVec outer_attrs, AST::Visibility); std::unique_ptr<AST::TraitItemConst> parse_trait_const (AST::AttrVec outer_attrs); - std::unique_ptr<AST::Param> parse_self_param (); + + tl::expected<std::unique_ptr<AST::Param>, ParseSelfError> parse_self_param (); + std::unique_ptr<AST::Impl> parse_impl (AST::Visibility vis, AST::AttrVec outer_attrs); std::unique_ptr<AST::InherentImplItem> |