From: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com> Exclusive range pattern were not handled by the parser as this an experimental feature.
gcc/rust/ChangeLog: * ast/rust-pattern.cc (tokenid_to_rangekind): Add a new function to get a range kind from the current token type. (RangePattern::as_string): Change the string representation for range pattern in order to handle excluded ranges. * ast/rust-pattern.h (enum class): Add new enum class to differentiate range kinds. (tokenid_to_rangekind): New prototype for a function that converts a token id to it's corresponding range kind. (class RangePattern): Change the class to accept a range kind instead of an ellipsis boolean. * hir/rust-ast-lower-pattern.cc (ASTLoweringPattern::visit): Abort when an excluded pattern has been found as we do not handle their lowering yet. * parse/rust-parse-impl.h (Parser::parse_literal_or_range_pattern): Parse excluded range patterns. (Parser::parse_pattern_no_alt): Likewise. (Parser::parse_ident_leading_pattern): Likewise. Signed-off-by: Pierre-Emmanuel Patry <pierre-emmanuel.pa...@embecosm.com> --- gcc/rust/ast/rust-pattern.cc | 31 ++++++++++++++++++++---- gcc/rust/ast/rust-pattern.h | 32 ++++++++++++++++++------- gcc/rust/hir/rust-ast-lower-pattern.cc | 3 +++ gcc/rust/parse/rust-parse-impl.h | 33 +++++++++++++++----------- 4 files changed, 72 insertions(+), 27 deletions(-) diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc index 85b3f5f3f51..98fd8e52f5f 100644 --- a/gcc/rust/ast/rust-pattern.cc +++ b/gcc/rust/ast/rust-pattern.cc @@ -30,6 +30,22 @@ along with GCC; see the file COPYING3. If not see namespace Rust { namespace AST { +RangeKind +tokenid_to_rangekind (TokenId id) +{ + switch (id) + { + case DOT_DOT_EQ: + return RangeKind::INCLUDED; + case ELLIPSIS: + return RangeKind::ELLIPSIS; + case DOT_DOT: + return RangeKind::EXCLUDED; + default: + rust_unreachable (); + } +} + std::string LiteralPattern::as_string () const { @@ -73,10 +89,17 @@ std::string RangePattern::as_string () const { // TODO: maybe rewrite to work with non-linearisable bounds - if (has_ellipsis_syntax) - return lower->as_string () + "..." + upper->as_string (); - else - return lower->as_string () + "..=" + upper->as_string (); + switch (range_kind) + { + case RangeKind::EXCLUDED: + return lower->as_string () + ".." + upper->as_string (); + case RangeKind::INCLUDED: + return lower->as_string () + "..=" + upper->as_string (); + case RangeKind::ELLIPSIS: + return lower->as_string () + "..." + upper->as_string (); + default: + rust_unreachable (); + } } std::string diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h index 7cb09a5c2ab..383a5ee40a7 100644 --- a/gcc/rust/ast/rust-pattern.h +++ b/gcc/rust/ast/rust-pattern.h @@ -368,13 +368,22 @@ protected: } }; +enum class RangeKind +{ + INCLUDED, + ELLIPSIS, + EXCLUDED, +}; + +RangeKind +tokenid_to_rangekind (TokenId id); // AST node for matching within a certain range (range pattern) class RangePattern : public Pattern { std::unique_ptr<RangePatternBound> lower; std::unique_ptr<RangePatternBound> upper; - bool has_ellipsis_syntax; + RangeKind range_kind; /* location only stored to avoid a dereference - lower pattern should give * correct location so maybe change in future */ @@ -386,10 +395,10 @@ public: // Constructor RangePattern (std::unique_ptr<RangePatternBound> lower, - std::unique_ptr<RangePatternBound> upper, location_t locus, - bool has_ellipsis_syntax = false) + std::unique_ptr<RangePatternBound> upper, RangeKind range_kind, + location_t locus) : lower (std::move (lower)), upper (std::move (upper)), - has_ellipsis_syntax (has_ellipsis_syntax), locus (locus), + range_kind (range_kind), locus (locus), node_id (Analysis::Mappings::get ().get_next_node_id ()) {} @@ -397,7 +406,7 @@ public: RangePattern (RangePattern const &other) : lower (other.lower->clone_range_pattern_bound ()), upper (other.upper->clone_range_pattern_bound ()), - has_ellipsis_syntax (other.has_ellipsis_syntax), locus (other.locus), + range_kind (other.range_kind), locus (other.locus), node_id (other.node_id) {} @@ -406,7 +415,7 @@ public: { lower = other.lower->clone_range_pattern_bound (); upper = other.upper->clone_range_pattern_bound (); - has_ellipsis_syntax = other.has_ellipsis_syntax; + range_kind = other.range_kind; locus = other.locus; node_id = other.node_id; @@ -419,11 +428,16 @@ public: location_t get_locus () const override final { return locus; } - bool get_has_ellipsis_syntax () { return has_ellipsis_syntax; } + bool get_has_ellipsis_syntax () const + { + return range_kind == RangeKind::ELLIPSIS; + } + + RangeKind get_range_kind () const { return range_kind; } - bool get_has_lower_bound () { return lower != nullptr; } + bool get_has_lower_bound () const { return lower != nullptr; } - bool get_has_upper_bound () { return upper != nullptr; } + bool get_has_upper_bound () const { return upper != nullptr; } void accept_vis (ASTVisitor &vis) override; diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc index b64cf3ae069..b7a4c564782 100644 --- a/gcc/rust/hir/rust-ast-lower-pattern.cc +++ b/gcc/rust/hir/rust-ast-lower-pattern.cc @@ -18,6 +18,7 @@ #include "rust-ast-lower-pattern.h" #include "rust-ast-lower-expr.h" +#include "rust-system.h" namespace Rust { namespace HIR { @@ -253,6 +254,8 @@ ASTLoweringPattern::visit (AST::LiteralPattern &pattern) void ASTLoweringPattern::visit (AST::RangePattern &pattern) { + if (pattern.get_range_kind () == AST::RangeKind::EXCLUDED) + rust_unreachable (); // Not supported yet auto upper_bound = lower_range_pattern_bound (pattern.get_upper_bound ()); auto lower_bound = lower_range_pattern_bound (pattern.get_lower_bound ()); diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index 91f09f64fe3..cabfb5bf5e2 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -10261,8 +10261,10 @@ Parser<ManagedTokenSource>::parse_literal_or_range_pattern () } const_TokenPtr next = lexer.peek_token (); - if (next->get_id () == DOT_DOT_EQ || next->get_id () == ELLIPSIS) + if (next->get_id () == DOT_DOT_EQ || next->get_id () == ELLIPSIS + || next->get_id () == DOT_DOT) { + AST::RangeKind kind = AST::tokenid_to_rangekind (next->get_id ()); // range pattern lexer.skip_token (); std::unique_ptr<AST::RangePatternBound> lower ( @@ -10283,7 +10285,7 @@ Parser<ManagedTokenSource>::parse_literal_or_range_pattern () } return std::unique_ptr<AST::RangePattern> ( - new AST::RangePattern (std::move (lower), std::move (upper), + new AST::RangePattern (std::move (lower), std::move (upper), kind, range_lower->get_locus ())); } else @@ -10532,11 +10534,12 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt () = parse_qualified_path_in_expression (); if (lexer.peek_token ()->get_id () == DOT_DOT_EQ - || lexer.peek_token ()->get_id () == ELLIPSIS) + || lexer.peek_token ()->get_id () == ELLIPSIS + || lexer.peek_token ()->get_id () == DOT_DOT) { // qualified range pattern bound, so parse rest of range pattern - bool has_ellipsis_syntax - = lexer.peek_token ()->get_id () == ELLIPSIS; + AST::RangeKind kind + = AST::tokenid_to_rangekind (lexer.peek_token ()->get_id ()); lexer.skip_token (); std::unique_ptr<AST::RangePatternBoundQualPath> lower_bound ( @@ -10546,8 +10549,8 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt () return std::unique_ptr<AST::RangePattern> ( new AST::RangePattern (std::move (lower_bound), - std::move (upper_bound), t->get_locus (), - has_ellipsis_syntax)); + std::move (upper_bound), kind, + t->get_locus ())); } else { @@ -10569,10 +10572,10 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt () switch (next->get_id ()) { case DOT_DOT_EQ: + case DOT_DOT: case ELLIPSIS: { // qualified range pattern bound, so parse rest of range pattern - bool has_ellipsis_syntax - = lexer.peek_token ()->get_id () == ELLIPSIS; + AST::RangeKind kind = AST::tokenid_to_rangekind (next->get_id ()); lexer.skip_token (); std::unique_ptr<AST::RangePatternBoundPath> lower_bound ( @@ -10582,8 +10585,8 @@ Parser<ManagedTokenSource>::parse_pattern_no_alt () return std::unique_ptr<AST::RangePattern> ( new AST::RangePattern (std::move (lower_bound), - std::move (upper_bound), - UNKNOWN_LOCATION, has_ellipsis_syntax)); + std::move (upper_bound), kind, + UNKNOWN_LOCATION)); } case EXCLAM: return parse_macro_invocation_partial (std::move (path), @@ -11093,9 +11096,11 @@ Parser<ManagedTokenSource>::parse_ident_leading_pattern () std::move (elems))); } case DOT_DOT_EQ: + case DOT_DOT: case ELLIPSIS: { // range - bool has_ellipsis_syntax = lexer.peek_token ()->get_id () == ELLIPSIS; + AST::RangeKind kind + = AST::tokenid_to_rangekind (lexer.peek_token ()->get_id ()); lexer.skip_token (); @@ -11106,8 +11111,8 @@ Parser<ManagedTokenSource>::parse_ident_leading_pattern () return std::unique_ptr<AST::RangePattern> ( new AST::RangePattern (std::move (lower_bound), - std::move (upper_bound), UNKNOWN_LOCATION, - has_ellipsis_syntax)); + std::move (upper_bound), kind, + UNKNOWN_LOCATION)); } case PATTERN_BIND: { // only allow on single-segment paths -- 2.45.2