[COMMITTED 72/77] gccrs: Move SlicePattern RestPattern handling

[email protected]
Newsgroups gmane.comp.gcc.patches,gmane.comp.gcc.rust
Message-ID <[email protected]>
From: Owen Avery <[email protected]>

This allows the AST to represent SlicePattern instances with more than
one RestPattern child, which allows us to handle invalid SlicePattern
instances which would be cfg'd out and mostly avoid dealing with the
implications of a RestPattern until HIR lowering.

gcc/rust/ChangeLog:

	* ast/rust-ast-collector.cc
	(TokenCollector::visit (SlicePatternItemsNoRest)): Remove
	function definition.
	(TokenCollector::visit (SlicePatternItemsHasRest)): Likewise.
	(TokenCollector::visit (SlicePattern)): Handle sub-patterns.
	* ast/rust-ast-collector.h
	(TokenCollector::visit (SlicePatternItemsNoRest)): Remove
	function declaration.
	(TokenCollector::visit (SlicePatternItemsHasRest)): Likewise.
	* ast/rust-ast-full-decls.h (class SlicePatternItemsNoRest):
	Remove forward declaration.
	(class SlicePatternItemsHasRest): Likewise.
	* ast/rust-ast-pointer-visitor.cc
	(PointerVisitor::visit (SlicePatternItemsNoRest)): Remove
	function definition.
	(PointerVisitor::visit (SlicePatternItemsHasRest)): Likewise.
	(PointerVisitor::visit (SlicePattern)): New function
	definition.
	* ast/rust-ast-pointer-visitor.h
	(PointerVisitor::visit (SlicePatternItemsNoRest)): Remove
	function declaration.
	(PointerVisitor::visit (SlicePatternItemsHasRest)): Likewise.
	(PointerVisitor::visit (SlicePattern)): New function
	declaration.
	* ast/rust-ast-visitor.cc
	(DefaultASTVisitor::visit (SlicePatternItemsNoRest)): Remove
	function definition.
	(DefaultASTVisitor::visit (SlicePatternItemsHasRest)): Likewise.
	(DefaultASTVisitor::visit (SlicePattern)): Handle sub-patterns.
	* ast/rust-ast-visitor.h
	(ASTVisitor::visit (SlicePatternItemsNoRest)): Remove function
	declaration.
	(ASTVisitor::visit (SlicePatternItemsHasRest)): Likewise.
	(DefaultASTVisitor::visit (SlicePatternItemsNoRest)): Likewise.
	(DefaultASTVisitor::visit (SlicePatternItemsHasRest)): Likewise.
	* ast/rust-pattern.cc (SlicePatternItemsNoRest::as_string):
	Remove function definition.
	(SlicePatternItemsHasRest::as_string): Likewise.
	(SlicePattern::as_string): Use as_string on sub patterns
	directly.
	(SlicePatternItemsNoRest::accept_vis): Remove function
	definition.
	(SlicePatternItemsHasRest::accept_vis): Likewise.
	* ast/rust-pattern.h (class SlicePatternItems): Remove.
	(class SlicePatternItemsNoRest): Remove.
	(class SlicePatternItemsHasRest): Remove.
	(SlicePattern::items): Remove member variable.
	(SlicePattern::patterns): New member variable.
	(SlicePattern::SlicePattern): Adjust to match member variable
	adjustments.
	(SlicePattern::get_items): Remove function.
	(SlicePattern::get_patterns): New function.
	(class CloneableDelegate<std::unique_ptr<SlicePatternItems>>):
	Remove specialization.
	* checks/errors/rust-ast-validation.cc
	(ASTValidation::visit (SlicePattern)): New function to check for
	too many RestPattern sub-patterns.
	* checks/errors/rust-ast-validation.h
	(ASTValidation::visit (SlicePattern)): New function declaration.
	* expand/rust-cfg-strip.cc
	(CfgStrip::visit (SlicePatternItemsNoRest)): Remove function
	definition.
	(CfgStrip::visit (SlicePatternItemsHasRest)): Likewise.
	(CfgStrip::visit (SlicePattern)): Directly visit sub-patterns.
	* expand/rust-cfg-strip.h
	(CfgStrip::visit (SlicePatternItemsNoRest)): Remove function
	declaration.
	(CfgStrip::visit (SlicePatternItemsHasRest)): Likewise.
	* expand/rust-derive.h
	(DeriveVisitor::visit (SlicePatternItemsNoRest)): Remove
	function.
	(DeriveVisitor::visit (SlicePatternItemsHasRest)): Likewise.
	* hir/rust-ast-lower-base.cc
	(ASTLoweringBase::visit (SlicePatternItemsNoRest)): Remove
	function definition.
	(ASTLoweringBase::visit (SlicePatternItemsHasRest)): Likewise.
	(ASTLoweringBase::lower_slice_pattern_no_rest): Likewise.
	(ASTLoweringBase::lower_slice_pattern_has_rest): Likewise.
	* hir/rust-ast-lower-base.h
	(ASTLoweringBase::visit (SlicePatternItemsNoRest)): Remove
	function declaration.
	(ASTLoweringBase::visit (SlicePatternItemsHasRest)): Likewise.
	(ASTLoweringBase::lower_slice_pattern_no_rest): Likewise.
	(ASTLoweringBase::lower_slice_pattern_has_rest): Likewise.
	* hir/rust-ast-lower-pattern.cc (lower_pattern_seq): New
	function.
	(ASTLoweringPattern::visit (SlicePattern)): Handle changes to
	AST SlicePattern.
	* parse/rust-parse-impl-pattern.hxx
	(Parser::parse_slice_pattern): Likewise.

gcc/testsuite/ChangeLog:

	* rust/compile/slice_rest_pattern.rs: Verify that too many rest
	patterns in a slice pattern does not produce an error, if that
	slice pattern is cfg'd out.

Signed-off-by: Owen Avery <[email protected]>
---
 gcc/rust/ast/rust-ast-collector.cc            |  26 +---
 gcc/rust/ast/rust-ast-collector.h             |   2 -
 gcc/rust/ast/rust-ast-full-decls.h            |   2 -
 gcc/rust/ast/rust-ast-pointer-visitor.cc      |  15 +--
 gcc/rust/ast/rust-ast-pointer-visitor.h       |   3 +-
 gcc/rust/ast/rust-ast-visitor.cc              |  19 +--
 gcc/rust/ast/rust-ast-visitor.h               |   4 -
 gcc/rust/ast/rust-pattern.cc                  |  51 +-------
 gcc/rust/ast/rust-pattern.h                   | 123 +-----------------
 gcc/rust/checks/errors/rust-ast-validation.cc |  19 +++
 gcc/rust/checks/errors/rust-ast-validation.h  |   1 +
 gcc/rust/expand/rust-cfg-strip.cc             |  35 +----
 gcc/rust/expand/rust-cfg-strip.h              |   2 -
 gcc/rust/expand/rust-derive.h                 |   2 -
 gcc/rust/hir/rust-ast-lower-base.cc           |  41 ------
 gcc/rust/hir/rust-ast-lower-base.h            |   8 --
 gcc/rust/hir/rust-ast-lower-pattern.cc        |  52 +++++---
 gcc/rust/parse/rust-parse-impl-pattern.hxx    |  96 +++-----------
 .../rust/compile/slice_rest_pattern.rs        |   3 +
 19 files changed, 96 insertions(+), 408 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-collector.cc b/gcc/rust/ast/rust-ast-collector.cc
index b478a8d4804..b6dd650e629 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -3055,36 +3055,12 @@ TokenCollector::visit (GroupedPattern &pattern)
   });
 }
 
-void
-TokenCollector::visit (SlicePatternItemsNoRest &items)
-{
-  visit_items_joined_by_separator (items.get_patterns (), COMMA);
-}
-
-void
-TokenCollector::visit (SlicePatternItemsHasRest &items)
-{
-  if (!items.get_lower_patterns ().empty ())
-    {
-      visit_items_joined_by_separator (items.get_lower_patterns (), COMMA);
-      push (Rust::Token::make (COMMA, UNDEF_LOCATION));
-    }
-
-  push (Rust::Token::make (DOT_DOT, UNDEF_LOCATION));
-
-  if (!items.get_upper_patterns ().empty ())
-    {
-      push (Rust::Token::make (COMMA, UNDEF_LOCATION));
-      visit_items_joined_by_separator (items.get_upper_patterns (), COMMA);
-    }
-}
-
 void
 TokenCollector::visit (SlicePattern &pattern)
 {
   describe_node (std::string ("SlicePattern"), [this, &pattern] () {
     push (Rust::Token::make (LEFT_SQUARE, pattern.get_locus ()));
-    visit (pattern.get_items ());
+    visit_items_joined_by_separator (pattern.get_patterns (), COMMA);
     push (Rust::Token::make (RIGHT_SQUARE, UNDEF_LOCATION));
   });
 }
diff --git a/gcc/rust/ast/rust-ast-collector.h b/gcc/rust/ast/rust-ast-collector.h
index 6f03f575862..e3cd703735c 100644
--- a/gcc/rust/ast/rust-ast-collector.h
+++ b/gcc/rust/ast/rust-ast-collector.h
@@ -424,8 +424,6 @@ public:
   void visit (TuplePatternItemsHasRest &tuple_items);
   void visit (TuplePattern &pattern);
   void visit (GroupedPattern &pattern);
-  void visit (SlicePatternItemsNoRest &items);
-  void visit (SlicePatternItemsHasRest &items);
   void visit (SlicePattern &pattern);
   void visit (AltPattern &pattern);
 
diff --git a/gcc/rust/ast/rust-ast-full-decls.h b/gcc/rust/ast/rust-ast-full-decls.h
index 21bb686d4e7..cf8b060376b 100644
--- a/gcc/rust/ast/rust-ast-full-decls.h
+++ b/gcc/rust/ast/rust-ast-full-decls.h
@@ -247,8 +247,6 @@ class TuplePatternItemsNoRest;
 class TuplePatternItemsHasRest;
 class TuplePattern;
 class GroupedPattern;
-class SlicePatternItemsNoRest;
-class SlicePatternItemsHasRest;
 class SlicePattern;
 class AltPattern;
 
diff --git a/gcc/rust/ast/rust-ast-pointer-visitor.cc b/gcc/rust/ast/rust-ast-pointer-visitor.cc
index 40df7a08f4b..cea7ae64754 100644
--- a/gcc/rust/ast/rust-ast-pointer-visitor.cc
+++ b/gcc/rust/ast/rust-ast-pointer-visitor.cc
@@ -919,19 +919,10 @@ PointerVisitor::visit (AST::GroupedPattern &pattern)
 }
 
 void
-PointerVisitor::visit (AST::SlicePatternItemsNoRest &items)
+PointerVisitor::visit (AST::SlicePattern &pattern)
 {
-  for (auto &item : items.get_patterns ())
-    reseat (item);
-}
-
-void
-PointerVisitor::visit (AST::SlicePatternItemsHasRest &items)
-{
-  for (auto &item : items.get_lower_patterns ())
-    reseat (item);
-  for (auto &item : items.get_upper_patterns ())
-    reseat (item);
+  for (auto &pat : pattern.get_patterns ())
+    reseat (pat);
 }
 
 void
diff --git a/gcc/rust/ast/rust-ast-pointer-visitor.h b/gcc/rust/ast/rust-ast-pointer-visitor.h
index a12343e4532..498f99c4ae3 100644
--- a/gcc/rust/ast/rust-ast-pointer-visitor.h
+++ b/gcc/rust/ast/rust-ast-pointer-visitor.h
@@ -150,8 +150,7 @@ public:
   void visit (AST::TuplePatternItemsNoRest &tuple_items) override;
   void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
   void visit (AST::GroupedPattern &pattern) override;
-  void visit (AST::SlicePatternItemsNoRest &items) override;
-  void visit (AST::SlicePatternItemsHasRest &items) override;
+  void visit (AST::SlicePattern &pattern) override;
   void visit (AST::AltPattern &pattern) override;
   void visit (AST::LetStmt &stmt) override;
   void visit (AST::ExprStmt &stmt) override;
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index f7d33ffc44e..c800f2c30dc 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -1345,26 +1345,11 @@ DefaultASTVisitor::visit (AST::GroupedPattern &pattern)
   visit (pattern.get_pattern_in_parens ());
 }
 
-void
-DefaultASTVisitor::visit (AST::SlicePatternItemsNoRest &items)
-{
-  for (auto &item : items.get_patterns ())
-    visit (item);
-}
-
-void
-DefaultASTVisitor::visit (AST::SlicePatternItemsHasRest &items)
-{
-  for (auto &item : items.get_lower_patterns ())
-    visit (item);
-  for (auto &item : items.get_upper_patterns ())
-    visit (item);
-}
-
 void
 DefaultASTVisitor::visit (AST::SlicePattern &pattern)
 {
-  visit (pattern.get_items ());
+  for (auto &pat : pattern.get_patterns ())
+    visit (pat);
 }
 
 void
diff --git a/gcc/rust/ast/rust-ast-visitor.h b/gcc/rust/ast/rust-ast-visitor.h
index c3ec4362b50..4ca56d139e9 100644
--- a/gcc/rust/ast/rust-ast-visitor.h
+++ b/gcc/rust/ast/rust-ast-visitor.h
@@ -212,8 +212,6 @@ public:
   virtual void visit (TuplePatternItemsHasRest &tuple_items) = 0;
   virtual void visit (TuplePattern &pattern) = 0;
   virtual void visit (GroupedPattern &pattern) = 0;
-  virtual void visit (SlicePatternItemsNoRest &items) = 0;
-  virtual void visit (SlicePatternItemsHasRest &items) = 0;
   virtual void visit (SlicePattern &pattern) = 0;
   virtual void visit (AltPattern &pattern) = 0;
 
@@ -387,8 +385,6 @@ public:
   virtual void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
   virtual void visit (AST::TuplePattern &pattern) override;
   virtual void visit (AST::GroupedPattern &pattern) override;
-  virtual void visit (AST::SlicePatternItemsNoRest &items) override;
-  virtual void visit (AST::SlicePatternItemsHasRest &items) override;
   virtual void visit (AST::SlicePattern &pattern) override;
   virtual void visit (AST::AltPattern &pattern) override;
   virtual void visit (AST::EmptyStmt &stmt) override;
diff --git a/gcc/rust/ast/rust-pattern.cc b/gcc/rust/ast/rust-pattern.cc
index e8bf1c9911e..750c586a097 100644
--- a/gcc/rust/ast/rust-pattern.cc
+++ b/gcc/rust/ast/rust-pattern.cc
@@ -327,52 +327,17 @@ GroupedExpr::as_string () const
 }
 
 std::string
-SlicePatternItemsNoRest::as_string () const
+SlicePattern::as_string () const
 {
   std::string str;
 
+  str = "SlicePattern: ";
   for (const auto &pattern : patterns.get ())
     str += "\n " + pattern->as_string ();
 
   return str;
 }
 
-std::string
-SlicePatternItemsHasRest::as_string () const
-{
-  std::string str;
-
-  str += "\n Lower patterns: ";
-  if (lower_patterns.get ().empty ())
-    {
-      str += "none";
-    }
-  else
-    {
-      for (const auto &lower : lower_patterns.get ())
-	str += "\n  " + lower->as_string ();
-    }
-
-  str += "\n Upper patterns: ";
-  if (upper_patterns.get ().empty ())
-    {
-      str += "none";
-    }
-  else
-    {
-      for (const auto &upper : upper_patterns.get ())
-	str += "\n  " + upper->as_string ();
-    }
-
-  return str;
-}
-
-std::string
-SlicePattern::as_string () const
-{
-  return "SlicePattern: " + items.get ()->as_string ();
-}
-
 std::string
 AltPattern::as_string () const
 {
@@ -402,18 +367,6 @@ GroupedExpr::accept_vis (ASTVisitor &vis)
   vis.visit (*this);
 }
 
-void
-SlicePatternItemsNoRest::accept_vis (ASTVisitor &vis)
-{
-  vis.visit (*this);
-}
-
-void
-SlicePatternItemsHasRest::accept_vis (ASTVisitor &vis)
-{
-  vis.visit (*this);
-}
-
 void
 SlicePattern::accept_vis (ASTVisitor &vis)
 {
diff --git a/gcc/rust/ast/rust-pattern.h b/gcc/rust/ast/rust-pattern.h
index 78780f3cc22..a175ff670fe 100644
--- a/gcc/rust/ast/rust-pattern.h
+++ b/gcc/rust/ast/rust-pattern.h
@@ -1211,117 +1211,19 @@ protected:
   }
 };
 
-// Base abstract class representing patterns in a SlicePattern
-class SlicePatternItems : public PatternItems
-{
-public:
-  // Unique pointer custom clone function
-  std::unique_ptr<SlicePatternItems> clone_slice_pattern_items () const
-  {
-    return std::unique_ptr<SlicePatternItems> (clone_pattern_items_impl ());
-  }
-
-protected:
-  // pure virtual clone implementation
-  virtual SlicePatternItems *clone_pattern_items_impl () const = 0;
-};
-
-// Class representing the patterns in a SlicePattern without `..`
-class SlicePatternItemsNoRest : public SlicePatternItems
-{
-  Cloneable<std::vector<std::unique_ptr<Pattern>>> patterns;
-
-public:
-  SlicePatternItemsNoRest (std::vector<std::unique_ptr<Pattern>> patterns)
-    : patterns (std::move (patterns))
-  {}
-
-  std::string as_string () const override;
-
-  void accept_vis (ASTVisitor &vis) override;
-
-  // TODO: seems kinda dodgy. Think of better way.
-  std::vector<std::unique_ptr<Pattern>> &get_patterns ()
-  {
-    return patterns.get ();
-  }
-  const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
-  {
-    return patterns.get ();
-  }
-
-  ItemType get_item_type () const override { return ItemType::NO_REST; }
-
-protected:
-  /* Use covariance to implement clone function as returning this object rather
-   * than base */
-  SlicePatternItemsNoRest *clone_pattern_items_impl () const override
-  {
-    return new SlicePatternItemsNoRest (*this);
-  }
-};
-
-// Class representing the patterns in a SlicePattern that contains a `..`
-class SlicePatternItemsHasRest : public SlicePatternItems
-{
-  Cloneable<std::vector<std::unique_ptr<Pattern>>> lower_patterns;
-  Cloneable<std::vector<std::unique_ptr<Pattern>>> upper_patterns;
-
-public:
-  SlicePatternItemsHasRest (
-    std::vector<std::unique_ptr<Pattern>> lower_patterns,
-    std::vector<std::unique_ptr<Pattern>> upper_patterns)
-    : lower_patterns (std::move (lower_patterns)),
-      upper_patterns (std::move (upper_patterns))
-  {}
-
-  std::string as_string () const override;
-
-  void accept_vis (ASTVisitor &vis) override;
-
-  // TODO: seems kinda dodgy. Think of better way.
-  std::vector<std::unique_ptr<Pattern>> &get_lower_patterns ()
-  {
-    return lower_patterns.get ();
-  }
-  const std::vector<std::unique_ptr<Pattern>> &get_lower_patterns () const
-  {
-    return lower_patterns.get ();
-  }
-
-  // TODO: seems kinda dodgy. Think of better way.
-  std::vector<std::unique_ptr<Pattern>> &get_upper_patterns ()
-  {
-    return upper_patterns.get ();
-  }
-  const std::vector<std::unique_ptr<Pattern>> &get_upper_patterns () const
-  {
-    return upper_patterns.get ();
-  }
-
-  ItemType get_item_type () const override { return ItemType::HAS_REST; }
-
-protected:
-  /* Use covariance to implement clone function as returning this object rather
-   * than base */
-  SlicePatternItemsHasRest *clone_pattern_items_impl () const override
-  {
-    return new SlicePatternItemsHasRest (*this);
-  }
-};
-
 // AST node representing patterns that can match slices and arrays
 class SlicePattern : public Pattern
 {
-  Cloneable<std::unique_ptr<SlicePatternItems>> items;
+  Cloneable<std::vector<std::unique_ptr<Pattern>>> patterns;
   location_t locus;
   NodeId node_id;
 
 public:
   std::string as_string () const override;
 
-  SlicePattern (std::unique_ptr<SlicePatternItems> items, location_t locus)
-    : items (std::move (items)), locus (locus),
+  SlicePattern (std::vector<std::unique_ptr<Pattern>> patterns,
+		location_t locus)
+    : patterns (std::move (patterns)), locus (locus),
       node_id (Analysis::Mappings::get ().get_next_node_id ())
   {}
 
@@ -1330,10 +1232,9 @@ public:
   void accept_vis (ASTVisitor &vis) override;
 
   // TODO: seems kinda dodgy. Think of better way.
-  SlicePatternItems &get_items ()
+  std::vector<std::unique_ptr<Pattern>> &get_patterns ()
   {
-    rust_assert (items != nullptr);
-    return *items.get ();
+    return patterns.get ();
   }
 
   NodeId get_node_id () const override { return node_id; }
@@ -1436,18 +1337,6 @@ template <> struct CloneableDelegate<std::unique_ptr<AST::TuplePatternItems>>
   }
 };
 
-template <> struct CloneableDelegate<std::unique_ptr<AST::SlicePatternItems>>
-{
-  static std::unique_ptr<AST::SlicePatternItems>
-  clone (const std::unique_ptr<AST::SlicePatternItems> &other)
-  {
-    if (other == nullptr)
-      return nullptr;
-    else
-      return other->clone_slice_pattern_items ();
-  }
-};
-
 template <> struct CloneableDelegate<std::unique_ptr<AST::StructPatternField>>
 {
   static std::unique_ptr<AST::StructPatternField>
diff --git a/gcc/rust/checks/errors/rust-ast-validation.cc b/gcc/rust/checks/errors/rust-ast-validation.cc
index 52831e26eb1..e3262b947cb 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.cc
+++ b/gcc/rust/checks/errors/rust-ast-validation.cc
@@ -198,4 +198,23 @@ ASTValidation::visit (AST::Module &module)
   AST::ContextualASTVisitor::visit (module);
 }
 
+void
+ASTValidation::visit (AST::SlicePattern &pattern)
+{
+  // TODO: store/use first rest pattern location?
+  //       for nicer errors
+  bool had_rest = false;
+
+  for (auto &pat : pattern.get_patterns ())
+    {
+      if (pat->get_pattern_kind () == AST::Pattern::Kind::Rest)
+	{
+	  if (had_rest)
+	    rust_error_at (pat->get_locus (),
+			   "%<..%> can only be used once per slice pattern");
+	  had_rest = true;
+	}
+    }
+}
+
 } // namespace Rust
diff --git a/gcc/rust/checks/errors/rust-ast-validation.h b/gcc/rust/checks/errors/rust-ast-validation.h
index 2e4fcee9c27..c8eb302e720 100644
--- a/gcc/rust/checks/errors/rust-ast-validation.h
+++ b/gcc/rust/checks/errors/rust-ast-validation.h
@@ -41,6 +41,7 @@ public:
   virtual void visit (AST::Union &item);
   virtual void visit (AST::Function &function);
   virtual void visit (AST::Trait &trait);
+  virtual void visit (AST::SlicePattern &pattern);
 };
 
 } // namespace Rust
diff --git a/gcc/rust/expand/rust-cfg-strip.cc b/gcc/rust/expand/rust-cfg-strip.cc
index 514ddbac467..a5c4c7c1358 100644
--- a/gcc/rust/expand/rust-cfg-strip.cc
+++ b/gcc/rust/expand/rust-cfg-strip.cc
@@ -2440,43 +2440,18 @@ CfgStrip::visit (AST::GroupedPattern &pattern)
 }
 
 void
-CfgStrip::visit (AST::SlicePatternItemsNoRest &items)
+CfgStrip::visit (AST::SlicePattern &pattern)
 {
-  AST::DefaultASTVisitor::visit (items);
+  AST::DefaultASTVisitor::visit (pattern);
   // can't strip individual patterns, only sub-patterns
-  for (auto &pattern : items.get_patterns ())
+  for (auto &sub_pat : pattern.get_patterns ())
     {
-      if (pattern->is_marked_for_strip ())
-	rust_error_at (pattern->get_locus (),
+      if (sub_pat->is_marked_for_strip ())
+	rust_error_at (sub_pat->get_locus (),
 		       "cannot strip pattern in this position");
     }
 }
 
-void
-CfgStrip::visit (AST::SlicePatternItemsHasRest &items)
-{
-  AST::DefaultASTVisitor::visit (items);
-  // can't strip individual patterns, only sub-patterns
-  for (auto &pattern : items.get_lower_patterns ())
-    {
-      if (pattern->is_marked_for_strip ())
-	rust_error_at (pattern->get_locus (),
-		       "cannot strip pattern in this position");
-    }
-  for (auto &pattern : items.get_upper_patterns ())
-    {
-      if (pattern->is_marked_for_strip ())
-	rust_error_at (pattern->get_locus (),
-		       "cannot strip pattern in this position");
-    }
-}
-
-void
-CfgStrip::visit (AST::SlicePattern &pattern)
-{
-  AST::DefaultASTVisitor::visit (pattern);
-}
-
 void
 CfgStrip::visit (AST::AltPattern &pattern)
 {
diff --git a/gcc/rust/expand/rust-cfg-strip.h b/gcc/rust/expand/rust-cfg-strip.h
index e372744f62d..2619ed58a4c 100644
--- a/gcc/rust/expand/rust-cfg-strip.h
+++ b/gcc/rust/expand/rust-cfg-strip.h
@@ -180,8 +180,6 @@ public:
   void visit (AST::TuplePatternItemsNoRest &tuple_items) override;
   void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
   void visit (AST::GroupedPattern &pattern) override;
-  void visit (AST::SlicePatternItemsNoRest &items) override;
-  void visit (AST::SlicePatternItemsHasRest &items) override;
   void visit (AST::SlicePattern &pattern) override;
   void visit (AST::AltPattern &pattern) override;
 
diff --git a/gcc/rust/expand/rust-derive.h b/gcc/rust/expand/rust-derive.h
index 3309c919aa3..6706191262f 100644
--- a/gcc/rust/expand/rust-derive.h
+++ b/gcc/rust/expand/rust-derive.h
@@ -232,8 +232,6 @@ private:
   virtual void visit (TuplePatternItemsHasRest &tuple_items) override final{};
   virtual void visit (TuplePattern &pattern) override final{};
   virtual void visit (GroupedPattern &pattern) override final{};
-  virtual void visit (SlicePatternItemsNoRest &items) override final{};
-  virtual void visit (SlicePatternItemsHasRest &items) override final{};
   virtual void visit (SlicePattern &pattern) override final{};
   virtual void visit (AltPattern &pattern) override final{};
   virtual void visit (EmptyStmt &stmt) override final{};
diff --git a/gcc/rust/hir/rust-ast-lower-base.cc b/gcc/rust/hir/rust-ast-lower-base.cc
index 7cbe52af629..70a98866dce 100644
--- a/gcc/rust/hir/rust-ast-lower-base.cc
+++ b/gcc/rust/hir/rust-ast-lower-base.cc
@@ -504,12 +504,6 @@ void
 ASTLoweringBase::visit (AST::GroupedPattern &)
 {}
 void
-ASTLoweringBase::visit (AST::SlicePatternItemsNoRest &)
-{}
-void
-ASTLoweringBase::visit (AST::SlicePatternItemsHasRest &)
-{}
-void
 ASTLoweringBase::visit (AST::SlicePattern &)
 {}
 void
@@ -942,41 +936,6 @@ ASTLoweringBase::lower_tuple_pattern_ranged (
 				       std::move (upper_patterns)));
 }
 
-std::unique_ptr<HIR::SlicePatternItems>
-ASTLoweringBase::lower_slice_pattern_no_rest (
-  AST::SlicePatternItemsNoRest &pattern)
-{
-  std::vector<std::unique_ptr<HIR::Pattern>> patterns;
-  patterns.reserve (pattern.get_patterns ().size ());
-  for (auto &p : pattern.get_patterns ())
-    patterns.emplace_back (ASTLoweringPattern::translate (*p));
-
-  return std::unique_ptr<HIR::SlicePatternItems> (
-    new HIR::SlicePatternItemsNoRest (std::move (patterns)));
-}
-
-std::unique_ptr<HIR::SlicePatternItems>
-ASTLoweringBase::lower_slice_pattern_has_rest (
-  AST::SlicePatternItemsHasRest &pattern)
-{
-  std::vector<std::unique_ptr<HIR::Pattern>> lower_patterns;
-  lower_patterns.reserve (pattern.get_lower_patterns ().size ());
-  std::vector<std::unique_ptr<HIR::Pattern>> upper_patterns;
-  upper_patterns.reserve (pattern.get_upper_patterns ().size ());
-
-  for (auto &p : pattern.get_lower_patterns ())
-    lower_patterns.emplace_back (
-      std::unique_ptr<HIR::Pattern> (ASTLoweringPattern::translate (*p)));
-
-  for (auto &p : pattern.get_upper_patterns ())
-    upper_patterns.emplace_back (
-      std::unique_ptr<HIR::Pattern> (ASTLoweringPattern::translate (*p)));
-
-  return std::unique_ptr<HIR::SlicePatternItems> (
-    new HIR::SlicePatternItemsHasRest (std::move (lower_patterns),
-				       std::move (upper_patterns)));
-}
-
 std::unique_ptr<HIR::RangePatternBound>
 ASTLoweringBase::lower_range_pattern_bound (AST::RangePatternBound &bound)
 {
diff --git a/gcc/rust/hir/rust-ast-lower-base.h b/gcc/rust/hir/rust-ast-lower-base.h
index ff1e51eb21b..cfc09becf37 100644
--- a/gcc/rust/hir/rust-ast-lower-base.h
+++ b/gcc/rust/hir/rust-ast-lower-base.h
@@ -236,8 +236,6 @@ public:
   virtual void visit (AST::TuplePatternItemsHasRest &tuple_items) override;
   virtual void visit (AST::TuplePattern &pattern) override;
   virtual void visit (AST::GroupedPattern &pattern) override;
-  virtual void visit (AST::SlicePatternItemsNoRest &items) override;
-  virtual void visit (AST::SlicePatternItemsHasRest &items) override;
   virtual void visit (AST::SlicePattern &pattern) override;
   virtual void visit (AST::AltPattern &pattern) override;
 
@@ -322,12 +320,6 @@ protected:
   std::unique_ptr<TuplePatternItems>
   lower_tuple_pattern_ranged (AST::TuplePatternItemsHasRest &pattern);
 
-  std::unique_ptr<SlicePatternItems>
-  lower_slice_pattern_no_rest (AST::SlicePatternItemsNoRest &pattern);
-
-  std::unique_ptr<SlicePatternItems>
-  lower_slice_pattern_has_rest (AST::SlicePatternItemsHasRest &pattern);
-
   std::unique_ptr<HIR::RangePatternBound>
   lower_range_pattern_bound (AST::RangePatternBound &bound);
 
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc
index 2a2751adaa9..b19a6411d2e 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.cc
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -338,27 +338,49 @@ ASTLoweringPattern::visit (AST::ReferencePattern &pattern)
     }
 }
 
+template <typename It>
+static std::vector<std::unique_ptr<HIR::Pattern>>
+lower_pattern_seq (It begin, It end)
+{
+  std::vector<std::unique_ptr<HIR::Pattern>> ret;
+  ret.reserve (end - begin);
+  for (auto it = begin; it != end; it++)
+    ret.emplace_back (ASTLoweringPattern::translate (**it));
+  return ret;
+}
+
 void
 ASTLoweringPattern::visit (AST::SlicePattern &pattern)
 {
+  tl::optional<size_t> rest_index;
+
+  std::vector<std::unique_ptr<AST::Pattern>> &sub_patterns
+    = pattern.get_patterns ();
+
+  for (size_t i = 0; i < sub_patterns.size (); i++)
+    {
+      auto &pat = sub_patterns[i];
+      if (pat->get_pattern_kind () == AST::Pattern::Kind::Rest)
+	{
+	  rest_index = i;
+	  // ASTValidation verified there's only one Rest pattern
+	  break;
+	}
+    }
+
   std::unique_ptr<HIR::SlicePatternItems> items;
 
-  switch (pattern.get_items ().get_item_type ())
+  if (rest_index)
     {
-    case AST::SlicePatternItems::ItemType::NO_REST:
-      {
-	auto &ref
-	  = static_cast<AST::SlicePatternItemsNoRest &> (pattern.get_items ());
-	items = ASTLoweringBase::lower_slice_pattern_no_rest (ref);
-      }
-      break;
-    case AST::SlicePatternItems::ItemType::HAS_REST:
-      {
-	auto &ref
-	  = static_cast<AST::SlicePatternItemsHasRest &> (pattern.get_items ());
-	items = ASTLoweringBase::lower_slice_pattern_has_rest (ref);
-      }
-      break;
+      auto rest_it = sub_patterns.begin () + *rest_index;
+      items = std::make_unique<HIR::SlicePatternItemsHasRest> (
+	lower_pattern_seq (sub_patterns.begin (), rest_it),
+	lower_pattern_seq (rest_it + 1, sub_patterns.end ()));
+    }
+  else
+    {
+      items = std::make_unique<HIR::SlicePatternItemsNoRest> (
+	lower_pattern_seq (sub_patterns.begin (), sub_patterns.end ()));
     }
 
   auto crate_num = mappings.get_current_crate ();
diff --git a/gcc/rust/parse/rust-parse-impl-pattern.hxx b/gcc/rust/parse/rust-parse-impl-pattern.hxx
index ab972d61ed2..2c1fe7596d8 100644
--- a/gcc/rust/parse/rust-parse-impl-pattern.hxx
+++ b/gcc/rust/parse/rust-parse-impl-pattern.hxx
@@ -525,73 +525,26 @@ std::unique_ptr<AST::SlicePattern>
 Parser<ManagedTokenSource>::parse_slice_pattern ()
 {
   location_t square_locus = lexer.peek_token ()->get_locus ();
-  std::vector<std::unique_ptr<AST::Pattern>> patterns;
-  tl::optional<std::vector<std::unique_ptr<AST::Pattern>>> upper_patterns
-    = tl::nullopt;
-
-  // lambda function to determine which vector to push new patterns into
-  auto get_pattern_ref
-    = [&] () -> std::vector<std::unique_ptr<AST::Pattern>> & {
-    return upper_patterns.has_value () ? upper_patterns.value () : patterns;
-  };
+  std::vector<std::unique_ptr<AST::Pattern>> sub_patterns;
 
   skip_token (LEFT_SQUARE);
 
-  if (lexer.peek_token ()->get_id () == RIGHT_SQUARE)
-    {
-      skip_token (RIGHT_SQUARE);
-      std::unique_ptr<AST::SlicePatternItemsNoRest> items (
-	new AST::SlicePatternItemsNoRest (std::move (patterns)));
-      return std::unique_ptr<AST::SlicePattern> (
-	new AST::SlicePattern (std::move (items), square_locus));
-    }
+  bool is_first = true;
 
-  // parse initial pattern (required)
-  if (lexer.peek_token ()->get_id () == DOT_DOT)
+  while (true)
     {
-      lexer.skip_token ();
-      upper_patterns = std::vector<std::unique_ptr<AST::Pattern>> ();
-    }
-  else
-    {
-      // Not a rest pattern `..`, parse normally
-      std::unique_ptr<AST::Pattern> initial_pattern = parse_pattern ();
-      if (initial_pattern == nullptr)
-	{
-	  Error error (lexer.peek_token ()->get_locus (),
-		       "failed to parse initial pattern in slice pattern");
-	  add_error (std::move (error));
+      const_TokenPtr t = lexer.peek_token ();
 
-	  return nullptr;
+      if (!is_first && t->get_id () == COMMA)
+	{
+	  skip_token (COMMA);
+	  t = lexer.peek_token ();
 	}
 
-      patterns.push_back (std::move (initial_pattern));
-    }
-
-  const_TokenPtr t = lexer.peek_token ();
-  while (t->get_id () == COMMA)
-    {
-      lexer.skip_token ();
-
-      // break if end bracket
-      if (lexer.peek_token ()->get_id () == RIGHT_SQUARE)
-	break;
-
-      if (lexer.peek_token ()->get_id () == DOT_DOT)
+      if (t->get_id () == RIGHT_SQUARE)
 	{
-	  if (upper_patterns.has_value ())
-	    {
-	      // DOT_DOT has been parsed before
-	      Error error (lexer.peek_token ()->get_locus (), "%s",
-			   "`..` can only be used once per slice pattern");
-	      add_error (std::move (error));
-
-	      return nullptr;
-	    }
-	  upper_patterns = std::vector<std::unique_ptr<AST::Pattern>> ();
-	  lexer.skip_token ();
-	  t = lexer.peek_token ();
-	  continue;
+	  skip_token (RIGHT_SQUARE);
+	  break;
 	}
 
       // parse pattern (required)
@@ -601,34 +554,17 @@ Parser<ManagedTokenSource>::parse_slice_pattern ()
 	  Error error (lexer.peek_token ()->get_locus (),
 		       "failed to parse pattern in slice pattern");
 	  add_error (std::move (error));
+	  // TODO: skip until closing square bracket
 
 	  return nullptr;
 	}
-      get_pattern_ref ().push_back (std::move (pattern));
-
-      t = lexer.peek_token ();
-    }
 
-  if (!skip_token (RIGHT_SQUARE))
-    {
-      return nullptr;
-    }
-
-  if (upper_patterns.has_value ())
-    {
-      // Slice pattern with rest
-      std::unique_ptr<AST::SlicePatternItemsHasRest> items (
-	new AST::SlicePatternItemsHasRest (
-	  std::move (patterns), std::move (upper_patterns.value ())));
-      return std::unique_ptr<AST::SlicePattern> (
-	new AST::SlicePattern (std::move (items), square_locus));
+      sub_patterns.push_back (std::move (pattern));
+      is_first = false;
     }
 
-  // Rest-less slice pattern
-  std::unique_ptr<AST::SlicePatternItemsNoRest> items (
-    new AST::SlicePatternItemsNoRest (std::move (patterns)));
-  return std::unique_ptr<AST::SlicePattern> (
-    new AST::SlicePattern (std::move (items), square_locus));
+  return std::make_unique<AST::SlicePattern> (std::move (sub_patterns),
+					      square_locus);
 }
 
 /* Parses an identifier pattern (pattern that binds a value matched to a
diff --git a/gcc/testsuite/rust/compile/slice_rest_pattern.rs b/gcc/testsuite/rust/compile/slice_rest_pattern.rs
index 08608b8479a..8cf7c2a8821 100644
--- a/gcc/testsuite/rust/compile/slice_rest_pattern.rs
+++ b/gcc/testsuite/rust/compile/slice_rest_pattern.rs
@@ -8,3 +8,6 @@ pub fn foo(a: &[u32]) {
         _ => {}
     }
 }
+
+#[cfg(any())]
+pub fn foo([.., ..]: ()) {}
-- 
2.50.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.