From: Lucas Ly Ba <[email protected]>

This patch refactors all uses of vector patterns since a vector of
patterns would be considered as an alt pattern, a vector is considered
useless.

gcc/rust/ChangeLog:

        * ast/rust-ast-builder.cc (Builder::match_arm): Moves the vector of 
patterns
        to a single pattern.
        * ast/rust-ast-collector.cc (TokenCollector::visit):Likewise.
        * ast/rust-ast-pointer-visitor.cc (PointerVisitor::visit):Likewise.
        * ast/rust-ast-visitor.cc (DefaultASTVisitor::visit):Likewise.
        * ast/rust-ast.cc (IfLetExpr::as_string):Likewise.
        (WhileLetLoopExpr::as_string):Likewise.
        (MatchArm::as_string):Likewise.
        * ast/rust-desugar-question-mark.cc (make_match_arm):Likewise.
        * ast/rust-desugar-while-let.cc (DesugarWhileLet::desugar):Likewise.
        * ast/rust-expr.h (class WhileLetLoopExpr):Likewise.
        (class IfLetExpr):Likewise.
        * backend/rust-compile-expr.cc (CompileExpr::visit):Likewise.
        * checks/errors/rust-hir-pattern-analysis.cc (lower_arm):Likewise.
        * expand/rust-cfg-strip.cc (CfgStrip::visit):Likewise.
        * hir/rust-ast-lower.cc (ASTLoweringIfLetBlock::desugar_iflet):Likewise.
        (ASTLoweringExprWithBlock::visit):Likewise.
        * hir/rust-hir-dump.cc (Dump::do_matcharm):Likewise.
        (Dump::visit):Likewise.
        * hir/tree/rust-hir-expr.cc (OperatorExpr::operator=):Likewise.
        (ArithmeticOrLogicalExpr::operator=):Likewise.
        (ComparisonExpr::operator=):Likewise.
        (LazyBooleanExpr::operator=):Likewise.
        (TypeCastExpr::operator=):Likewise.
        (AssignmentExpr::operator=):Likewise.
        (CompoundAssignmentExpr::operator=):Likewise.
        (GroupedExpr::operator=):Likewise.
        (ArrayExpr::operator=):Likewise.
        (ArrayIndexExpr::operator=):Likewise.
        (CallExpr::operator=):Likewise.
        (MethodCallExpr::operator=):Likewise.
        (FieldAccessExpr::operator=):Likewise.
        (BlockExpr::operator=):Likewise.
        (BreakExpr::operator=):Likewise.
        (ReturnExpr::operator=):Likewise.
        (UnsafeBlockExpr::operator=):Likewise.
        (BaseLoopExpr::operator=):Likewise.
        (WhileLetLoopExpr::WhileLetLoopExpr):Likewise.
        (WhileLetLoopExpr::operator=):Likewise.
        (MatchArm::MatchArm):Likewise.
        (MatchArm::operator=):Likewise.
        (MatchExpr::operator=):Likewise.
        * hir/tree/rust-hir-expr.h (class WhileLetLoopExpr):Likewise.
        * hir/tree/rust-hir-visitor.cc (DefaultHIRVisitor::walk):Likewise.
        (DefaultHIRVisitor::visit_match_arm):Likewise.
        * hir/tree/rust-hir.cc (WhileLetLoopExpr::as_string):Likewise.
        (MatchArm::as_string):Likewise.
        * parse/rust-parse-impl-expr.hxx: Likewise.
        * parse/rust-parse-impl.hxx: Likewise.
        * parse/rust-parse.h:Likewise.
        * resolve/rust-default-resolver.cc 
(DefaultResolver::visit_if_let_patterns):Likewise.
        * resolve/rust-late-name-resolver-2.0.cc (Late::visit):Likewise.
        * typecheck/rust-hir-type-check-expr.cc (TypeCheckExpr::visit):Likewise.

Signed-off-by: Lucas Ly Ba <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.


Commit on github: 
https://github.com/Rust-GCC/gccrs/commit/4239b704a7003ecc5cd8ba551382210f00066e0b

The commit has been mentioned in the following pull-request(s):
 - https://github.com/Rust-GCC/gccrs/pull/4297

 gcc/rust/ast/rust-ast-builder.cc              |  5 +-
 gcc/rust/ast/rust-ast-collector.cc            | 16 +---
 gcc/rust/ast/rust-ast-pointer-visitor.cc      |  9 +-
 gcc/rust/ast/rust-ast-visitor.cc              |  9 +-
 gcc/rust/ast/rust-ast.cc                      | 15 ++--
 gcc/rust/ast/rust-desugar-question-mark.cc    |  6 +-
 gcc/rust/ast/rust-desugar-while-let.cc        |  4 +-
 gcc/rust/ast/rust-expr.h                      | 88 +++++++------------
 gcc/rust/backend/rust-compile-expr.cc         | 82 +++++++++--------
 .../errors/rust-hir-pattern-analysis.cc       |  4 +-
 gcc/rust/expand/rust-cfg-strip.cc             | 28 +++---
 gcc/rust/hir/rust-ast-lower.cc                | 28 +++---
 gcc/rust/hir/rust-hir-dump.cc                 |  4 +-
 gcc/rust/hir/tree/rust-hir-expr.cc            | 78 ++++------------
 gcc/rust/hir/tree/rust-hir-expr.h             | 24 ++---
 gcc/rust/hir/tree/rust-hir-visitor.cc         |  6 +-
 gcc/rust/hir/tree/rust-hir.cc                 | 20 ++---
 gcc/rust/parse/rust-parse-impl-expr.hxx       | 24 ++---
 gcc/rust/parse/rust-parse-impl.hxx            | 55 +++---------
 gcc/rust/parse/rust-parse.h                   |  3 +-
 gcc/rust/resolve/rust-default-resolver.cc     |  3 +-
 .../resolve/rust-late-name-resolver-2.0.cc    |  6 +-
 .../typecheck/rust-hir-type-check-expr.cc     | 36 ++++----
 23 files changed, 194 insertions(+), 359 deletions(-)

diff --git a/gcc/rust/ast/rust-ast-builder.cc b/gcc/rust/ast/rust-ast-builder.cc
index 632f9455e..75ad312c3 100644
--- a/gcc/rust/ast/rust-ast-builder.cc
+++ b/gcc/rust/ast/rust-ast-builder.cc
@@ -484,10 +484,7 @@ Builder::match (std::unique_ptr<Expr> &&scrutinee,
 MatchArm
 Builder::match_arm (std::unique_ptr<Pattern> &&pattern)
 {
-  auto patterns = std::vector<std::unique_ptr<Pattern>> ();
-  patterns.emplace_back (std::move (pattern));
-
-  return MatchArm (std::move (patterns), loc);
+  return MatchArm (std::move (pattern), loc);
 }
 
 MatchCase
diff --git a/gcc/rust/ast/rust-ast-collector.cc 
b/gcc/rust/ast/rust-ast-collector.cc
index db146cdd2..07497eae2 100644
--- a/gcc/rust/ast/rust-ast-collector.cc
+++ b/gcc/rust/ast/rust-ast-collector.cc
@@ -1617,11 +1617,7 @@ TokenCollector::visit (WhileLetLoopExpr &expr)
     visit_loop_common (expr);
     push (Rust::Token::make (WHILE, expr.get_locus ()));
     push (Rust::Token::make (LET, UNDEF_LOCATION));
-    // TODO: The reference mention only one Pattern
-    for (auto &item : expr.get_patterns ())
-      {
-       visit (item);
-      }
+    visit (expr.get_pattern ());
     push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
     visit (expr.get_scrutinee_expr ());
     visit (expr.get_loop_block ());
@@ -1669,10 +1665,7 @@ TokenCollector::visit (IfLetExpr &expr)
   describe_node (std::string ("IfLetExpr"), [this, &expr] () {
     push (Rust::Token::make (IF, expr.get_locus ()));
     push (Rust::Token::make (LET, UNDEF_LOCATION));
-    for (auto &pattern : expr.get_patterns ())
-      {
-       visit (pattern);
-      }
+    visit (expr.get_pattern ());
     push (Rust::Token::make (EQUAL, UNDEF_LOCATION));
     visit (expr.get_value_expr ());
     visit (expr.get_if_block ());
@@ -1695,10 +1688,7 @@ TokenCollector::visit (MatchArm &arm)
 {
   describe_node (std::string ("MatchArm"), [this, &arm] () {
     visit_items_as_lines (arm.get_outer_attrs ());
-    for (auto &pattern : arm.get_patterns ())
-      {
-       visit (pattern);
-      }
+    visit (arm.get_pattern ());
     if (arm.has_match_arm_guard ())
       {
        push (Rust::Token::make (IF, UNDEF_LOCATION));
diff --git a/gcc/rust/ast/rust-ast-pointer-visitor.cc 
b/gcc/rust/ast/rust-ast-pointer-visitor.cc
index ee1f001e1..c3d28e833 100644
--- a/gcc/rust/ast/rust-ast-pointer-visitor.cc
+++ b/gcc/rust/ast/rust-ast-pointer-visitor.cc
@@ -587,8 +587,7 @@ void
 PointerVisitor::visit (AST::WhileLetLoopExpr &expr)
 {
   visit_outer_attrs (expr);
-  for (auto &pattern : expr.get_patterns ())
-    reseat (pattern);
+  reseat (expr.get_pattern ());
 
   if (expr.has_loop_label ())
     visit (expr.get_loop_label ());
@@ -627,8 +626,7 @@ void
 PointerVisitor::visit (AST::IfLetExpr &expr)
 {
   visit_outer_attrs (expr);
-  for (auto &pattern : expr.get_patterns ())
-    reseat (pattern);
+  reseat (expr.get_pattern ());
   reseat (expr.get_value_expr_ptr ());
   visit (expr.get_if_block ());
 }
@@ -644,8 +642,7 @@ void
 PointerVisitor::visit (AST::MatchArm &arm)
 {
   visit_outer_attrs (arm);
-  for (auto &pattern : arm.get_patterns ())
-    reseat (pattern);
+  reseat (arm.get_pattern ());
   if (arm.has_match_arm_guard ())
     reseat (arm.get_guard_expr_ptr ());
 }
diff --git a/gcc/rust/ast/rust-ast-visitor.cc b/gcc/rust/ast/rust-ast-visitor.cc
index a9e2f053a..b04d08d95 100644
--- a/gcc/rust/ast/rust-ast-visitor.cc
+++ b/gcc/rust/ast/rust-ast-visitor.cc
@@ -607,8 +607,7 @@ void
 DefaultASTVisitor::visit (AST::WhileLetLoopExpr &expr)
 {
   visit_outer_attrs (expr);
-  for (auto &pattern : expr.get_patterns ())
-    visit (pattern);
+  visit (expr.get_pattern ());
 
   if (expr.has_loop_label ())
     visit (expr.get_loop_label ());
@@ -647,8 +646,7 @@ void
 DefaultASTVisitor::visit (AST::IfLetExpr &expr)
 {
   visit_outer_attrs (expr);
-  for (auto &pattern : expr.get_patterns ())
-    visit (pattern);
+  visit (expr.get_pattern ());
   visit (expr.get_value_expr ());
   visit (expr.get_if_block ());
 }
@@ -664,8 +662,7 @@ void
 DefaultASTVisitor::visit (AST::MatchArm &arm)
 {
   visit_outer_attrs (arm);
-  for (auto &pattern : arm.get_patterns ())
-    visit (pattern);
+  visit (arm.get_pattern ());
   if (arm.has_match_arm_guard ())
     visit (arm.get_guard_expr ());
 }
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index f15cc3d3c..7302dcf6b 100644
--- a/gcc/rust/ast/rust-ast.cc
+++ b/gcc/rust/ast/rust-ast.cc
@@ -1943,14 +1943,13 @@ IfLetExpr::as_string () const
   str += append_attributes (outer_attrs, OUTER);
 
   str += "\n Condition match arm patterns: ";
-  if (match_arm_patterns.empty ())
+  if (match_arm_pattern == nullptr)
     {
       str += "none";
     }
   else
     {
-      for (const auto &pattern : match_arm_patterns)
-       str += "\n  " + pattern->as_string ();
+      str += "\n  " + match_arm_pattern->as_string ();
     }
 
   str += "\n Scrutinee expr: " + value->as_string ();
@@ -2167,14 +2166,13 @@ WhileLetLoopExpr::as_string () const
     str += get_loop_label ().as_string ();
 
   str += "\n Match arm patterns: ";
-  if (match_arm_patterns.empty ())
+  if (match_arm_pattern == nullptr)
     {
       str += "none";
     }
   else
     {
-      for (const auto &pattern : match_arm_patterns)
-       str += "\n  " + pattern->as_string ();
+      str += "\n  " + match_arm_pattern->as_string ();
     }
 
   str += "\n Scrutinee expr: " + scrutinee->as_string ();
@@ -2253,14 +2251,13 @@ MatchArm::as_string () const
   std::string str = append_attributes (outer_attrs, OUTER);
 
   str += "\nPatterns: ";
-  if (match_arm_patterns.empty ())
+  if (match_arm_pattern == nullptr)
     {
       str += "none";
     }
   else
     {
-      for (const auto &pattern : match_arm_patterns)
-       str += "\n " + pattern->as_string ();
+      str += "\n " + match_arm_pattern->as_string ();
     }
 
   str += "\nGuard expr: ";
diff --git a/gcc/rust/ast/rust-desugar-question-mark.cc 
b/gcc/rust/ast/rust-desugar-question-mark.cc
index 20a490396..b3419af05 100644
--- a/gcc/rust/ast/rust-desugar-question-mark.cc
+++ b/gcc/rust/ast/rust-desugar-question-mark.cc
@@ -39,11 +39,7 @@ MatchArm
 make_match_arm (std::unique_ptr<Pattern> &&pattern)
 {
   auto loc = pattern->get_locus ();
-
-  auto patterns = std::vector<std::unique_ptr<Pattern>> ();
-  patterns.emplace_back (std::move (pattern));
-
-  return MatchArm (std::move (patterns), loc);
+  return MatchArm (std::move (pattern), loc);
 }
 
 MatchCase
diff --git a/gcc/rust/ast/rust-desugar-while-let.cc 
b/gcc/rust/ast/rust-desugar-while-let.cc
index 5eadc5908..1e24e9453 100644
--- a/gcc/rust/ast/rust-desugar-while-let.cc
+++ b/gcc/rust/ast/rust-desugar-while-let.cc
@@ -53,9 +53,9 @@ DesugarWhileLet::DesugarCtx::make_continue_arm (
 std::unique_ptr<Expr>
 DesugarWhileLet::desugar (WhileLetLoopExpr &expr)
 {
-  rust_assert (expr.get_patterns ().size () == 1);
+  rust_assert (expr.get_pattern () != nullptr);
 
-  auto pattern = expr.get_patterns ()[0]->clone_pattern ();
+  auto pattern = expr.get_pattern ()->clone_pattern ();
   auto body = expr.get_loop_block ().clone_block_expr ();
   auto scrutinee = expr.get_scrutinee_expr ().clone_expr ();
 
diff --git a/gcc/rust/ast/rust-expr.h b/gcc/rust/ast/rust-expr.h
index 55a8df818..ce3f4141f 100644
--- a/gcc/rust/ast/rust-expr.h
+++ b/gcc/rust/ast/rust-expr.h
@@ -4292,14 +4292,14 @@ protected:
 class WhileLetLoopExpr : public BaseLoopExpr
 {
   // MatchArmPatterns patterns;
-  std::vector<std::unique_ptr<Pattern>> match_arm_patterns; // inlined
+  std::unique_ptr<Pattern> match_arm_pattern; // inlined
   std::unique_ptr<Expr> scrutinee;
 
 public:
   std::string as_string () const override;
 
   // Constructor with a loop label
-  WhileLetLoopExpr (std::vector<std::unique_ptr<Pattern>> match_arm_patterns,
+  WhileLetLoopExpr (std::unique_ptr<Pattern> match_arm_pattern,
                    std::unique_ptr<Expr> scrutinee,
                    std::unique_ptr<BlockExpr> loop_block, location_t locus,
                    tl::optional<LoopLabel> loop_label = tl::nullopt,
@@ -4307,7 +4307,7 @@ public:
                    = std::vector<Attribute> ())
     : BaseLoopExpr (std::move (loop_block), locus, std::move (loop_label),
                    std::move (outer_attribs)),
-      match_arm_patterns (std::move (match_arm_patterns)),
+      match_arm_pattern (std::move (match_arm_pattern)),
       scrutinee (std::move (scrutinee))
   {}
 
@@ -4317,25 +4317,15 @@ public:
       /*match_arm_patterns(other.match_arm_patterns),*/ scrutinee (
        other.scrutinee->clone_expr ())
   {
-    match_arm_patterns.reserve (other.match_arm_patterns.size ());
-    for (const auto &e : other.match_arm_patterns)
-      match_arm_patterns.push_back (e->clone_pattern ());
+    match_arm_pattern = other.get_pattern ()->clone_pattern ();
   }
 
   // Overloaded assignment operator to clone pointers
   WhileLetLoopExpr &operator= (WhileLetLoopExpr const &other)
   {
     BaseLoopExpr::operator= (other);
-    // match_arm_patterns = other.match_arm_patterns;
     scrutinee = other.scrutinee->clone_expr ();
-    // loop_block = other.loop_block->clone_block_expr();
-    // loop_label = other.loop_label;
-    // outer_attrs = other.outer_attrs;
-
-    match_arm_patterns.reserve (other.match_arm_patterns.size ());
-    for (const auto &e : other.match_arm_patterns)
-      match_arm_patterns.push_back (e->clone_pattern ());
-
+    match_arm_pattern = other.get_pattern ()->clone_pattern ();
     return *this;
   }
 
@@ -4359,14 +4349,11 @@ public:
   }
 
   // TODO: this mutable getter seems really dodgy. Think up better way.
-  const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
-  {
-    return match_arm_patterns;
-  }
-  std::vector<std::unique_ptr<Pattern>> &get_patterns ()
+  const std::unique_ptr<Pattern> &get_pattern () const
   {
-    return match_arm_patterns;
+    return match_arm_pattern;
   }
+  std::unique_ptr<Pattern> &get_pattern () { return match_arm_pattern; }
 
   BaseLoopExpr::Kind get_loop_kind () const override
   {
@@ -4658,7 +4645,7 @@ protected:
 class IfLetExpr : public ExprWithBlock
 {
   std::vector<Attribute> outer_attrs;
-  std::vector<std::unique_ptr<Pattern>> match_arm_patterns; // inlined
+  std::unique_ptr<Pattern> match_arm_pattern; // inlined
   std::unique_ptr<Expr> value;
   std::unique_ptr<BlockExpr> if_block;
   location_t locus;
@@ -4666,11 +4653,11 @@ class IfLetExpr : public ExprWithBlock
 public:
   std::string as_string () const override;
 
-  IfLetExpr (std::vector<std::unique_ptr<Pattern>> match_arm_patterns,
+  IfLetExpr (std::unique_ptr<Pattern> match_arm_pattern,
             std::unique_ptr<Expr> value, std::unique_ptr<BlockExpr> if_block,
             std::vector<Attribute> outer_attrs, location_t locus)
     : outer_attrs (std::move (outer_attrs)),
-      match_arm_patterns (std::move (match_arm_patterns)),
+      match_arm_pattern (std::move (match_arm_pattern)),
       value (std::move (value)), if_block (std::move (if_block)), locus (locus)
   {}
 
@@ -4684,10 +4671,7 @@ public:
       value = other.value->clone_expr ();
     if (other.if_block != nullptr)
       if_block = other.if_block->clone_block_expr ();
-
-    match_arm_patterns.reserve (other.match_arm_patterns.size ());
-    for (const auto &e : other.match_arm_patterns)
-      match_arm_patterns.push_back (e->clone_pattern ());
+    match_arm_pattern = other.match_arm_pattern->clone_pattern ();
   }
 
   // overload assignment operator to clone
@@ -4707,10 +4691,10 @@ public:
     else
       if_block = nullptr;
 
-    match_arm_patterns.reserve (other.match_arm_patterns.size ());
-    for (const auto &e : other.match_arm_patterns)
-      match_arm_patterns.push_back (e->clone_pattern ());
+    if (other.if_block != nullptr)
+      if_block = other.if_block->clone_block_expr ();
 
+    match_arm_pattern = other.match_arm_pattern->clone_pattern ();
     return *this;
   }
 
@@ -4760,14 +4744,11 @@ public:
   }
 
   // TODO: this mutable getter seems really dodgy. Think up better way.
-  const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
+  const std::unique_ptr<Pattern> &get_pattern () const
   {
-    return match_arm_patterns;
-  }
-  std::vector<std::unique_ptr<Pattern>> &get_patterns ()
-  {
-    return match_arm_patterns;
+    return match_arm_pattern;
   }
+  std::unique_ptr<Pattern> &get_pattern () { return match_arm_pattern; }
 
   void set_outer_attrs (std::vector<Attribute> new_attrs) override
   {
@@ -4804,12 +4785,12 @@ class IfLetExprConseqElse : public IfLetExpr
 public:
   std::string as_string () const override;
 
-  IfLetExprConseqElse (std::vector<std::unique_ptr<Pattern>> 
match_arm_patterns,
+  IfLetExprConseqElse (std::unique_ptr<Pattern> match_arm_pattern,
                       std::unique_ptr<Expr> value,
                       std::unique_ptr<BlockExpr> if_block,
                       std::unique_ptr<ExprWithBlock> else_block,
                       std::vector<Attribute> outer_attrs, location_t locus)
-    : IfLetExpr (std::move (match_arm_patterns), std::move (value),
+    : IfLetExpr (std::move (match_arm_pattern), std::move (value),
                 std::move (if_block), std::move (outer_attrs), locus),
       else_block (std::move (else_block))
   {}
@@ -4861,7 +4842,7 @@ struct MatchArm
 private:
   std::vector<Attribute> outer_attrs;
   // MatchArmPatterns patterns;
-  std::vector<std::unique_ptr<Pattern>> match_arm_patterns; // inlined
+  std::unique_ptr<Pattern> match_arm_pattern; // inlined
 
   // bool has_match_arm_guard;
   // inlined from MatchArmGuard
@@ -4874,11 +4855,11 @@ public:
   bool has_match_arm_guard () const { return guard_expr != nullptr; }
 
   // Constructor for match arm with a guard expression
-  MatchArm (std::vector<std::unique_ptr<Pattern>> match_arm_patterns,
-           location_t locus, std::unique_ptr<Expr> guard_expr = nullptr,
+  MatchArm (std::unique_ptr<Pattern> match_arm_pattern, location_t locus,
+           std::unique_ptr<Expr> guard_expr = nullptr,
            std::vector<Attribute> outer_attrs = std::vector<Attribute> ())
     : outer_attrs (std::move (outer_attrs)),
-      match_arm_patterns (std::move (match_arm_patterns)),
+      match_arm_pattern (std::move (match_arm_pattern)),
       guard_expr (std::move (guard_expr)), locus (locus)
   {}
 
@@ -4889,9 +4870,7 @@ public:
     if (other.guard_expr != nullptr)
       guard_expr = other.guard_expr->clone_expr ();
 
-    match_arm_patterns.reserve (other.match_arm_patterns.size ());
-    for (const auto &e : other.match_arm_patterns)
-      match_arm_patterns.push_back (e->clone_pattern ());
+    match_arm_pattern = other.match_arm_pattern->clone_pattern ();
 
     locus = other.locus;
   }
@@ -4908,9 +4887,7 @@ public:
     else
       guard_expr = nullptr;
 
-    match_arm_patterns.reserve (other.match_arm_patterns.size ());
-    for (const auto &e : other.match_arm_patterns)
-      match_arm_patterns.push_back (e->clone_pattern ());
+    match_arm_pattern = other.match_arm_pattern->clone_pattern ();
 
     return *this;
   }
@@ -4920,13 +4897,13 @@ public:
   MatchArm &operator= (MatchArm &&other) = default;
 
   // Returns whether match arm is in an error state.
-  bool is_error () const { return match_arm_patterns.empty (); }
+  bool is_error () const { return match_arm_pattern == nullptr; }
 
   // Creates a match arm in an error state.
   static MatchArm create_error ()
   {
     location_t locus = UNDEF_LOCATION;
-    return MatchArm (std::vector<std::unique_ptr<Pattern>> (), locus);
+    return MatchArm (nullptr, locus);
   }
 
   std::string as_string () const;
@@ -4948,14 +4925,11 @@ public:
   const std::vector<Attribute> &get_outer_attrs () const { return outer_attrs; 
}
   std::vector<Attribute> &get_outer_attrs () { return outer_attrs; }
 
-  const std::vector<std::unique_ptr<Pattern>> &get_patterns () const
-  {
-    return match_arm_patterns;
-  }
-  std::vector<std::unique_ptr<Pattern>> &get_patterns ()
+  const std::unique_ptr<Pattern> &get_pattern () const
   {
-    return match_arm_patterns;
+    return match_arm_pattern;
   }
+  std::unique_ptr<Pattern> &get_pattern () { return match_arm_pattern; }
 
   location_t get_locus () const { return locus; }
 };
diff --git a/gcc/rust/backend/rust-compile-expr.cc 
b/gcc/rust/backend/rust-compile-expr.cc
index f2bca2d6d..a4379ca63 100644
--- a/gcc/rust/backend/rust-compile-expr.cc
+++ b/gcc/rust/backend/rust-compile-expr.cc
@@ -1193,60 +1193,58 @@ CompileExpr::visit (HIR::MatchExpr &expr)
     {
       // for now lets just get single pattern's working
       HIR::MatchArm &kase_arm = kase.get_arm ();
-      rust_assert (kase_arm.get_patterns ().size () > 0);
+      rust_assert (kase_arm.get_pattern () != nullptr);
 
-      for (auto &kase_pattern : kase_arm.get_patterns ())
-       {
-         // setup the match-arm-body-block
-         location_t start_location = UNKNOWN_LOCATION; // FIXME
-         location_t end_location = UNKNOWN_LOCATION;   // FIXME
-         tree arm_body_block = Backend::block (fndecl, enclosing_scope, {},
-                                               start_location, end_location);
+      auto &kase_pattern = kase_arm.get_pattern ();
+      // setup the match-arm-body-block
+      location_t start_location = UNKNOWN_LOCATION; // FIXME
+      location_t end_location = UNKNOWN_LOCATION;   // FIXME
+      tree arm_body_block = Backend::block (fndecl, enclosing_scope, {},
+                                           start_location, end_location);
 
-         ctx->push_block (arm_body_block);
+      ctx->push_block (arm_body_block);
 
-         // setup the bindings for the block
-         CompilePatternBindings::Compile (*kase_pattern, match_scrutinee_expr,
-                                          ctx);
+      // setup the bindings for the block
+      CompilePatternBindings::Compile (*kase_pattern, match_scrutinee_expr,
+                                      ctx);
 
-         // compile the expr and setup the assignment if required when tmp !=
-         // NULL
-         location_t arm_locus = kase_arm.get_locus ();
-         tree kase_expr_tree = CompileExpr::Compile (kase.get_expr (), ctx);
-         tree result_reference = Backend::var_expression (tmp, arm_locus);
+      // compile the expr and setup the assignment if required when tmp !=
+      // NULL
+      location_t arm_locus = kase_arm.get_locus ();
+      tree kase_expr_tree = CompileExpr::Compile (kase.get_expr (), ctx);
+      tree result_reference = Backend::var_expression (tmp, arm_locus);
 
-         TyTy::BaseType *actual = nullptr;
-         bool ok = ctx->get_tyctx ()->lookup_type (
-           kase.get_expr ().get_mappings ().get_hirid (), &actual);
-         rust_assert (ok);
+      TyTy::BaseType *actual = nullptr;
+      bool ok = ctx->get_tyctx ()->lookup_type (
+       kase.get_expr ().get_mappings ().get_hirid (), &actual);
+      rust_assert (ok);
 
-         tree coerced_result
-           = coercion_site (kase.get_expr ().get_mappings ().get_hirid (),
-                            kase_expr_tree, actual, expr_tyty,
-                            expr.get_locus (), arm_locus);
+      tree coerced_result
+       = coercion_site (kase.get_expr ().get_mappings ().get_hirid (),
+                        kase_expr_tree, actual, expr_tyty, expr.get_locus (),
+                        arm_locus);
 
-         tree assignment
-           = Backend::assignment_statement (result_reference, coerced_result,
-                                            arm_locus);
-         ctx->add_statement (assignment);
+      tree assignment
+       = Backend::assignment_statement (result_reference, coerced_result,
+                                        arm_locus);
+      ctx->add_statement (assignment);
 
-         // go to end label
-         tree goto_end_label
-           = build1_loc (arm_locus, GOTO_EXPR, void_type_node, end_label);
-         ctx->add_statement (goto_end_label);
+      // go to end label
+      tree goto_end_label
+       = build1_loc (arm_locus, GOTO_EXPR, void_type_node, end_label);
+      ctx->add_statement (goto_end_label);
 
-         ctx->pop_block ();
+      ctx->pop_block ();
 
-         tree check_expr
-           = CompilePatternCheckExpr::Compile (*kase_pattern,
-                                               match_scrutinee_expr, ctx);
+      tree check_expr
+       = CompilePatternCheckExpr::Compile (*kase_pattern, match_scrutinee_expr,
+                                           ctx);
 
-         tree check_stmt
-           = Backend::if_statement (NULL_TREE, check_expr, arm_body_block,
-                                    NULL_TREE, kase_pattern->get_locus ());
+      tree check_stmt
+       = Backend::if_statement (NULL_TREE, check_expr, arm_body_block,
+                                NULL_TREE, kase_pattern->get_locus ());
 
-         ctx->add_statement (check_stmt);
-       }
+      ctx->add_statement (check_stmt);
     }
 
   // setup the switch expression
diff --git a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc 
b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
index f132e04ef..24150a478 100644
--- a/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
+++ b/gcc/rust/checks/errors/rust-hir-pattern-analysis.cc
@@ -1463,10 +1463,10 @@ static MatchArm
 lower_arm (Resolver::TypeCheckContext *ctx, HIR::MatchCase &arm,
           TyTy::BaseType *scrutinee_ty)
 {
-  rust_assert (arm.get_arm ().get_patterns ().size () > 0);
+  rust_assert (arm.get_arm ().get_pattern () != nullptr);
 
   DeconstructedPat pat
-    = lower_pattern (ctx, *arm.get_arm ().get_patterns ().at (0), 
scrutinee_ty);
+    = lower_pattern (ctx, *arm.get_arm ().get_pattern (), scrutinee_ty);
   return MatchArm (pat, arm.get_arm ().has_match_arm_guard ());
 }
 
diff --git a/gcc/rust/expand/rust-cfg-strip.cc 
b/gcc/rust/expand/rust-cfg-strip.cc
index e8c6c3789..dde6e5ed9 100644
--- a/gcc/rust/expand/rust-cfg-strip.cc
+++ b/gcc/rust/expand/rust-cfg-strip.cc
@@ -1436,10 +1436,9 @@ CfgStrip::visit (AST::WhileLetLoopExpr &expr)
 
   AST::DefaultASTVisitor::visit (expr);
 
-  for (auto &pattern : expr.get_patterns ())
-    if (pattern->is_marked_for_strip ())
-      rust_error_at (pattern->get_locus (),
-                    "cannot strip pattern in this position");
+  if (expr.get_pattern ()->is_marked_for_strip ())
+    rust_error_at (expr.get_pattern ()->get_locus (),
+                  "cannot strip pattern in this position");
 
   // can't strip scrutinee expr itself, but can strip sub-expressions
   auto &scrutinee_expr = expr.get_scrutinee_expr ();
@@ -1566,10 +1565,9 @@ CfgStrip::visit (AST::IfLetExpr &expr)
 
   AST::DefaultASTVisitor::visit (expr);
 
-  for (auto &pattern : expr.get_patterns ())
-    if (pattern->is_marked_for_strip ())
-      rust_error_at (pattern->get_locus (),
-                    "cannot strip pattern in this position");
+  if (expr.get_pattern ()->is_marked_for_strip ())
+    rust_error_at (expr.get_pattern ()->get_locus (),
+                  "cannot strip pattern in this position");
 
   // can't strip value expr itself, but can strip sub-expressions
   auto &value_expr = expr.get_value_expr ();
@@ -1598,10 +1596,9 @@ CfgStrip::visit (AST::IfLetExprConseqElse &expr)
 
   AST::DefaultASTVisitor::visit (expr);
 
-  for (auto &pattern : expr.get_patterns ())
-    if (pattern->is_marked_for_strip ())
-      rust_error_at (pattern->get_locus (),
-                    "cannot strip pattern in this position");
+  if (expr.get_pattern ()->is_marked_for_strip ())
+    rust_error_at (expr.get_pattern ()->get_locus (),
+                  "cannot strip pattern in this position");
 
   // can't strip value expr itself, but can strip sub-expressions
   auto &value_expr = expr.get_value_expr ();
@@ -1668,10 +1665,9 @@ CfgStrip::visit (AST::MatchExpr &expr)
          continue;
        }
 
-      for (auto &pattern : match_arm.get_patterns ())
-       if (pattern->is_marked_for_strip ())
-         rust_error_at (pattern->get_locus (),
-                        "cannot strip pattern in this position");
+      if (match_arm.get_pattern ()->is_marked_for_strip ())
+       rust_error_at (match_arm.get_pattern ()->get_locus (),
+                      "cannot strip pattern in this position");
 
       /* assuming that guard expression cannot be stripped as
        * strictly speaking you would have to strip the whole guard to
diff --git a/gcc/rust/hir/rust-ast-lower.cc b/gcc/rust/hir/rust-ast-lower.cc
index 758bc59f5..14559370b 100644
--- a/gcc/rust/hir/rust-ast-lower.cc
+++ b/gcc/rust/hir/rust-ast-lower.cc
@@ -228,8 +228,7 @@ ASTLoweringIfLetBlock::desugar_iflet (AST::IfLetExpr &expr,
                                      std::vector<HIR::MatchCase> &match_arms)
 {
   HIR::Expr *kase_expr;
-  std::vector<std::unique_ptr<HIR::Pattern>> match_arm_patterns;
-  match_arm_patterns.reserve (expr.get_patterns ().size ());
+  std::unique_ptr<HIR::Pattern> match_arm_pattern;
 
   *branch_value = ASTLoweringExpr::translate (expr.get_value_expr ());
   kase_expr = ASTLoweringExpr::translate (expr.get_if_block ());
@@ -237,13 +236,13 @@ ASTLoweringIfLetBlock::desugar_iflet (AST::IfLetExpr 
&expr,
   // (stable) if let only accepts a single pattern, but (unstable) if let 
chains
   // need more than one pattern.
   // We don't support if let chains, so only support a single pattern.
-  rust_assert (expr.get_patterns ().size () == 1);
+  rust_assert (expr.get_pattern () != nullptr);
 
-  for (auto &pattern : expr.get_patterns ())
-    match_arm_patterns.emplace_back (ASTLoweringPattern::translate (*pattern));
+  match_arm_pattern
+    = ASTLoweringPattern::translate (*expr.get_pattern ())->clone_pattern ();
 
   // The match arm corresponding to the if let pattern when it matches.
-  HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (), 
nullptr,
+  HIR::MatchArm arm (std::move (match_arm_pattern), expr.get_locus (), nullptr,
                     {});
 
   auto crate_num = mappings.get_current_crate ();
@@ -255,15 +254,14 @@ ASTLoweringIfLetBlock::desugar_iflet (AST::IfLetExpr 
&expr,
                           std::unique_ptr<HIR::Expr> (kase_expr));
 
   // The default match arm when the if let pattern does not match
-  std::vector<std::unique_ptr<HIR::Pattern>> match_arm_patterns_wildcard;
   Analysis::NodeMapping mapping_default (crate_num, expr.get_node_id (),
                                         mappings.get_next_hir_id (crate_num),
                                         UNKNOWN_LOCAL_DEFID);
 
-  match_arm_patterns_wildcard.emplace_back (
+  auto match_arm_pattern_wildcard = std::unique_ptr<HIR::WildcardPattern> (
     new HIR::WildcardPattern (mapping_default, expr.get_locus ()));
 
-  HIR::MatchArm arm_default (std::move (match_arm_patterns_wildcard),
+  HIR::MatchArm arm_default (std::move (match_arm_pattern_wildcard),
                             expr.get_locus (), nullptr, {});
 
   match_arms.emplace_back (std::move (mapping_default), std::move 
(arm_default),
@@ -431,15 +429,13 @@ ASTLoweringExprWithBlock::visit (AST::MatchExpr &expr)
            match_case.get_arm ().get_guard_expr ());
        }
 
-      std::vector<std::unique_ptr<HIR::Pattern>> match_arm_patterns;
-      match_arm_patterns.reserve (
-       match_case.get_arm ().get_patterns ().size ());
+      std::unique_ptr<HIR::Pattern> match_arm_pattern;
 
-      for (auto &pattern : match_case.get_arm ().get_patterns ())
-       match_arm_patterns.emplace_back (
-         ASTLoweringPattern::translate (*pattern));
+      match_arm_pattern
+       = ASTLoweringPattern::translate (*match_case.get_arm ().get_pattern ())
+           ->clone_pattern ();
 
-      HIR::MatchArm arm (std::move (match_arm_patterns), expr.get_locus (),
+      HIR::MatchArm arm (std::move (match_arm_pattern), expr.get_locus (),
                         std::unique_ptr<HIR::Expr> (kase_guard_expr),
                         match_case.get_arm ().get_outer_attrs ());
 
diff --git a/gcc/rust/hir/rust-hir-dump.cc b/gcc/rust/hir/rust-hir-dump.cc
index c6e6a7cbd..8f75394ca 100644
--- a/gcc/rust/hir/rust-hir-dump.cc
+++ b/gcc/rust/hir/rust-hir-dump.cc
@@ -366,7 +366,7 @@ Dump::do_matcharm (MatchArm &e)
   begin ("MatchArm");
   // FIXME Can't remember how to handle that. Let's see later.
   // do_outer_attrs(e);
-  visit_collection ("match_arm_patterns", e.get_patterns ());
+  visit_field ("match_arm_pattern", e.get_pattern ());
   if (e.has_match_arm_guard ())
     visit_field ("guard_expr", e.get_guard_expr ());
   end ("MatchArm");
@@ -1461,7 +1461,7 @@ Dump::visit (WhileLetLoopExpr &e)
   begin ("WhileLetLoopExpr");
   do_baseloopexpr (e);
 
-  visit_collection ("match_arm_patterns", e.get_patterns ());
+  visit_field ("match_arm_patterns", e.get_pattern ());
 
   visit_field ("condition", e.get_cond ());
 
diff --git a/gcc/rust/hir/tree/rust-hir-expr.cc 
b/gcc/rust/hir/tree/rust-hir-expr.cc
index 383f113bb..949071735 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.cc
+++ b/gcc/rust/hir/tree/rust-hir-expr.cc
@@ -76,7 +76,6 @@ OperatorExpr::operator= (OperatorExpr const &other)
   ExprWithoutBlock::operator= (other);
   main_or_left_expr = other.main_or_left_expr->clone_expr ();
   locus = other.locus;
-  // outer_attrs = other.outer_attrs;
 
   return *this;
 }
@@ -130,7 +129,6 @@ ArithmeticOrLogicalExpr &
 ArithmeticOrLogicalExpr::operator= (ArithmeticOrLogicalExpr const &other)
 {
   OperatorExpr::operator= (other);
-  // main_or_left_expr = other.main_or_left_expr->clone_expr();
   right_expr = other.right_expr->clone_expr ();
   expr_type = other.expr_type;
 
@@ -155,10 +153,8 @@ ComparisonExpr &
 ComparisonExpr::operator= (ComparisonExpr const &other)
 {
   OperatorExpr::operator= (other);
-  // main_or_left_expr = other.main_or_left_expr->clone_expr();
   right_expr = other.right_expr->clone_expr ();
   expr_type = other.expr_type;
-  // outer_attrs = other.outer_attrs;
 
   return *this;
 }
@@ -181,7 +177,6 @@ LazyBooleanExpr &
 LazyBooleanExpr::operator= (LazyBooleanExpr const &other)
 {
   OperatorExpr::operator= (other);
-  // main_or_left_expr = other.main_or_left_expr->clone_expr();
   right_expr = other.right_expr->clone_expr ();
   expr_type = other.expr_type;
 
@@ -206,7 +201,6 @@ TypeCastExpr &
 TypeCastExpr::operator= (TypeCastExpr const &other)
 {
   OperatorExpr::operator= (other);
-  // main_or_left_expr = other.main_or_left_expr->clone_expr();
   type_to_convert_to = other.type_to_convert_to->clone_type ();
 
   return *this;
@@ -229,9 +223,7 @@ AssignmentExpr &
 AssignmentExpr::operator= (AssignmentExpr const &other)
 {
   OperatorExpr::operator= (other);
-  // main_or_left_expr = other.main_or_left_expr->clone_expr();
   right_expr = other.right_expr->clone_expr ();
-  // outer_attrs = other.outer_attrs;
 
   return *this;
 }
@@ -254,10 +246,8 @@ CompoundAssignmentExpr &
 CompoundAssignmentExpr::operator= (CompoundAssignmentExpr const &other)
 {
   OperatorExpr::operator= (other);
-  // main_or_left_expr = other.main_or_left_expr->clone_expr();
   right_expr = other.right_expr->clone_expr ();
   expr_type = other.expr_type;
-  // outer_attrs = other.outer_attrs;
 
   return *this;
 }
@@ -283,7 +273,6 @@ GroupedExpr::operator= (GroupedExpr const &other)
   inner_attrs = other.inner_attrs;
   expr_in_parens = other.expr_in_parens->clone_expr ();
   locus = other.locus;
-  // outer_attrs = other.outer_attrs;
 
   return *this;
 }
@@ -357,7 +346,6 @@ ArrayExpr::operator= (ArrayExpr const &other)
   if (other.has_array_elems ())
     internal_elements = other.internal_elements->clone_array_elems ();
   locus = other.locus;
-  // outer_attrs = other.outer_attrs;
 
   return *this;
 }
@@ -382,7 +370,6 @@ ArrayIndexExpr::operator= (ArrayIndexExpr const &other)
   ExprWithoutBlock::operator= (other);
   array_expr = other.array_expr->clone_expr ();
   index_expr = other.index_expr->clone_expr ();
-  // outer_attrs = other.outer_attrs;
   locus = other.locus;
 
   return *this;
@@ -607,8 +594,6 @@ CallExpr::operator= (CallExpr const &other)
   ExprWithoutBlock::operator= (other);
   function = other.function->clone_expr ();
   locus = other.locus;
-  // params = other.params;
-  // outer_attrs = other.outer_attrs;
 
   params.reserve (other.params.size ());
   for (const auto &e : other.params)
@@ -642,8 +627,6 @@ MethodCallExpr::operator= (MethodCallExpr const &other)
   receiver = other.receiver->clone_expr ();
   method_name = other.method_name;
   locus = other.locus;
-  // params = other.params;
-  // outer_attrs = other.outer_attrs;
 
   params.reserve (other.params.size ());
   for (const auto &e : other.params)
@@ -673,7 +656,6 @@ FieldAccessExpr::operator= (FieldAccessExpr const &other)
   receiver = other.receiver->clone_expr ();
   field = other.field;
   locus = other.locus;
-  // outer_attrs = other.outer_attrs;
 
   return *this;
 }
@@ -778,14 +760,12 @@ BlockExpr &
 BlockExpr::operator= (BlockExpr const &other)
 {
   ExprWithBlock::operator= (other);
-  // statements = other.statements;
   expr = other.expr->clone_expr ();
   inner_attrs = other.inner_attrs;
   start_locus = other.end_locus;
   end_locus = other.end_locus;
-  // outer_attrs = other.outer_attrs;
-
   statements.reserve (other.statements.size ());
+
   for (const auto &e : other.statements)
     statements.push_back (e->clone_stmt ());
 
@@ -878,7 +858,6 @@ BreakExpr::operator= (BreakExpr const &other)
   label = other.label;
   break_expr = other.break_expr->clone_expr ();
   locus = other.locus;
-  // outer_attrs = other.outer_attrs;
 
   return *this;
 }
@@ -1014,7 +993,6 @@ ReturnExpr::operator= (ReturnExpr const &other)
   ExprWithoutBlock::operator= (other);
   return_expr = other.return_expr->clone_expr ();
   locus = other.locus;
-  // outer_attrs = other.outer_attrs;
 
   return *this;
 }
@@ -1037,7 +1015,6 @@ UnsafeBlockExpr::operator= (UnsafeBlockExpr const &other)
   ExprWithBlock::operator= (other);
   expr = other.expr->clone_block_expr ();
   locus = other.locus;
-  // outer_attrs = other.outer_attrs;
 
   return *this;
 }
@@ -1064,7 +1041,6 @@ BaseLoopExpr::operator= (BaseLoopExpr const &other)
   loop_block = other.loop_block->clone_block_expr ();
   loop_label = other.loop_label;
   locus = other.locus;
-  // outer_attrs = other.outer_attrs;
 
   return *this;
 }
@@ -1097,48 +1073,34 @@ WhileLoopExpr::operator= (WhileLoopExpr const &other)
 {
   BaseLoopExpr::operator= (other);
   condition = other.condition->clone_expr ();
-  // loop_block = other.loop_block->clone_block_expr();
-  // loop_label = other.loop_label;
-  // outer_attrs = other.outer_attrs;
-
   return *this;
 }
 
-WhileLetLoopExpr::WhileLetLoopExpr (
-  Analysis::NodeMapping mappings,
-  std::vector<std::unique_ptr<Pattern>> match_arm_patterns,
-  std::unique_ptr<Expr> condition, std::unique_ptr<BlockExpr> loop_block,
-  location_t locus, tl::optional<LoopLabel> loop_label,
-  AST::AttrVec outer_attribs)
+WhileLetLoopExpr::WhileLetLoopExpr (Analysis::NodeMapping mappings,
+                                   std::unique_ptr<Pattern> match_arm_pattern,
+                                   std::unique_ptr<Expr> condition,
+                                   std::unique_ptr<BlockExpr> loop_block,
+                                   location_t locus,
+                                   tl::optional<LoopLabel> loop_label,
+                                   AST::AttrVec outer_attribs)
   : BaseLoopExpr (std::move (mappings), std::move (loop_block), locus,
                  std::move (loop_label), std::move (outer_attribs)),
-    match_arm_patterns (std::move (match_arm_patterns)),
+    match_arm_pattern (std::move (match_arm_pattern)),
     condition (std::move (condition))
 {}
 
 WhileLetLoopExpr::WhileLetLoopExpr (WhileLetLoopExpr const &other)
   : BaseLoopExpr (other),
-    /*match_arm_patterns(other.match_arm_patterns),*/ condition (
-      other.condition->clone_expr ())
-{
-  match_arm_patterns.reserve (other.match_arm_patterns.size ());
-  for (const auto &e : other.match_arm_patterns)
-    match_arm_patterns.push_back (e->clone_pattern ());
-}
+    match_arm_pattern (other.match_arm_pattern->clone_pattern ()),
+    condition (other.condition->clone_expr ())
+{}
 
 WhileLetLoopExpr &
 WhileLetLoopExpr::operator= (WhileLetLoopExpr const &other)
 {
   BaseLoopExpr::operator= (other);
-  // match_arm_patterns = other.match_arm_patterns;
   condition = other.condition->clone_expr ();
-  // loop_block = other.loop_block->clone_block_expr();
-  // loop_label = other.loop_label;
-  // outer_attrs = other.outer_attrs;
-
-  match_arm_patterns.reserve (other.match_arm_patterns.size ());
-  for (const auto &e : other.match_arm_patterns)
-    match_arm_patterns.push_back (e->clone_pattern ());
+  match_arm_pattern = other.match_arm_pattern->clone_pattern ();
 
   return *this;
 }
@@ -1191,11 +1153,11 @@ IfExprConseqElse::operator= (IfExprConseqElse const 
&other)
   return *this;
 }
 
-MatchArm::MatchArm (std::vector<std::unique_ptr<Pattern>> match_arm_patterns,
+MatchArm::MatchArm (std::unique_ptr<Pattern> match_arm_pattern,
                    location_t locus, std::unique_ptr<Expr> guard_expr,
                    AST::AttrVec outer_attrs)
   : outer_attrs (std::move (outer_attrs)),
-    match_arm_patterns (std::move (match_arm_patterns)),
+    match_arm_pattern (std::move (match_arm_pattern)),
     guard_expr (std::move (guard_expr)), locus (locus)
 {}
 
@@ -1205,9 +1167,7 @@ MatchArm::MatchArm (MatchArm const &other) : outer_attrs 
(other.outer_attrs)
   if (other.guard_expr != nullptr)
     guard_expr = other.guard_expr->clone_expr ();
 
-  match_arm_patterns.reserve (other.match_arm_patterns.size ());
-  for (const auto &e : other.match_arm_patterns)
-    match_arm_patterns.push_back (e->clone_pattern ());
+  match_arm_pattern = other.match_arm_pattern->clone_pattern ();
 
   locus = other.locus;
 }
@@ -1220,10 +1180,7 @@ MatchArm::operator= (MatchArm const &other)
   if (other.guard_expr != nullptr)
     guard_expr = other.guard_expr->clone_expr ();
 
-  match_arm_patterns.clear ();
-  match_arm_patterns.reserve (other.match_arm_patterns.size ());
-  for (const auto &e : other.match_arm_patterns)
-    match_arm_patterns.push_back (e->clone_pattern ());
+  match_arm_pattern = other.match_arm_pattern->clone_pattern ();
 
   return *this;
 }
@@ -1275,7 +1232,6 @@ MatchExpr::operator= (MatchExpr const &other)
   branch_value = other.branch_value->clone_expr ();
   inner_attrs = other.inner_attrs;
   match_arms = other.match_arms;
-  // outer_attrs = other.outer_attrs;
   locus = other.locus;
 
   /*match_arms.reserve (other.match_arms.size ());
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h 
b/gcc/rust/hir/tree/rust-hir-expr.h
index 88f6df200..eada40416 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -2498,7 +2498,7 @@ protected:
 class WhileLetLoopExpr : public BaseLoopExpr
 {
   // MatchArmPatterns patterns;
-  std::vector<std::unique_ptr<Pattern>> match_arm_patterns; // inlined
+  std::unique_ptr<Pattern> match_arm_pattern; // inlined
   std::unique_ptr<Expr> condition;
 
 public:
@@ -2506,7 +2506,7 @@ public:
 
   // Constructor with a loop label
   WhileLetLoopExpr (Analysis::NodeMapping mappings,
-                   std::vector<std::unique_ptr<Pattern>> match_arm_patterns,
+                   std::unique_ptr<Pattern> match_arm_pattern,
                    std::unique_ptr<Expr> condition,
                    std::unique_ptr<BlockExpr> loop_block, location_t locus,
                    tl::optional<LoopLabel> loop_label,
@@ -2526,10 +2526,7 @@ public:
   void accept_vis (HIRExpressionVisitor &vis) override;
 
   Expr &get_cond () { return *condition; }
-  std::vector<std::unique_ptr<Pattern>> &get_patterns ()
-  {
-    return match_arm_patterns;
-  }
+  std::unique_ptr<Pattern> &get_pattern () { return match_arm_pattern; }
 
 protected:
   /* Use covariance to implement clone function as returning this object rather
@@ -2671,7 +2668,7 @@ struct MatchArm
 {
 private:
   AST::AttrVec outer_attrs;
-  std::vector<std::unique_ptr<Pattern>> match_arm_patterns;
+  std::unique_ptr<Pattern> match_arm_pattern;
   std::unique_ptr<Expr> guard_expr;
   location_t locus;
 
@@ -2680,8 +2677,8 @@ public:
   bool has_match_arm_guard () const { return guard_expr != nullptr; }
 
   // Constructor for match arm with a guard expression
-  MatchArm (std::vector<std::unique_ptr<Pattern>> match_arm_patterns,
-           location_t locus, std::unique_ptr<Expr> guard_expr = nullptr,
+  MatchArm (std::unique_ptr<Pattern> match_arm_pattern, location_t locus,
+           std::unique_ptr<Expr> guard_expr = nullptr,
            AST::AttrVec outer_attrs = AST::AttrVec ());
 
   // Copy constructor with clone
@@ -2697,21 +2694,18 @@ public:
   MatchArm &operator= (MatchArm &&other) = default;
 
   // Returns whether match arm is in an error state.
-  bool is_error () const { return match_arm_patterns.empty (); }
+  bool is_error () const { return match_arm_pattern == nullptr; }
 
   // Creates a match arm in an error state.
   static MatchArm create_error ()
   {
     location_t locus = UNDEF_LOCATION;
-    return MatchArm (std::vector<std::unique_ptr<Pattern>> (), locus);
+    return MatchArm (nullptr, locus);
   }
 
   std::string to_string () const;
 
-  std::vector<std::unique_ptr<Pattern>> &get_patterns ()
-  {
-    return match_arm_patterns;
-  }
+  std::unique_ptr<Pattern> &get_pattern () { return match_arm_pattern; }
 
   Expr &get_guard_expr () { return *guard_expr; }
 
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.cc 
b/gcc/rust/hir/tree/rust-hir-visitor.cc
index 1e201a554..015cda772 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.cc
+++ b/gcc/rust/hir/tree/rust-hir-visitor.cc
@@ -479,8 +479,7 @@ void
 DefaultHIRVisitor::walk (WhileLetLoopExpr &expr)
 {
   visit_outer_attrs (expr);
-  for (auto &pattern : expr.get_patterns ())
-    pattern->accept_vis (*this);
+  expr.get_pattern ()->accept_vis (*this);
   if (expr.has_loop_label ())
     visit_loop_label (expr.get_loop_label ());
   expr.get_cond ().accept_vis (*this);
@@ -506,8 +505,7 @@ void
 DefaultHIRVisitor::visit_match_arm (MatchArm &arm)
 {
   // visit_outer_attrs (arm);
-  for (auto &pattern : arm.get_patterns ())
-    pattern->accept_vis (*this);
+  arm.get_pattern ()->accept_vis (*this);
   if (arm.has_match_arm_guard ())
     arm.get_guard_expr ().accept_vis (*this);
 }
diff --git a/gcc/rust/hir/tree/rust-hir.cc b/gcc/rust/hir/tree/rust-hir.cc
index 11cb35998..cc5d2062c 100644
--- a/gcc/rust/hir/tree/rust-hir.cc
+++ b/gcc/rust/hir/tree/rust-hir.cc
@@ -1775,16 +1775,13 @@ WhileLetLoopExpr::to_string () const
     }
 
   str += "\n Match arm patterns: ";
-  if (match_arm_patterns.empty ())
+  if (match_arm_pattern == nullptr)
     {
       str += "none";
     }
   else
     {
-      for (const auto &pattern : match_arm_patterns)
-       {
-         str += "\n  " + pattern->to_string ();
-       }
+      str += "\n  " + match_arm_pattern->to_string ();
     }
 
   str += "\n Scrutinee expr: " + condition->to_string ();
@@ -1898,17 +1895,10 @@ MatchArm::to_string () const
     }
 
   str += "\nPatterns: ";
-  if (match_arm_patterns.empty ())
-    {
-      str += "none";
-    }
+  if (match_arm_pattern == nullptr)
+    str += "none";
   else
-    {
-      for (const auto &pattern : match_arm_patterns)
-       {
-         str += "\n " + pattern->to_string ();
-       }
-    }
+    str += "\n " + match_arm_pattern->to_string ();
 
   str += "\nGuard expr: ";
   if (!has_match_arm_guard ())
diff --git a/gcc/rust/parse/rust-parse-impl-expr.hxx 
b/gcc/rust/parse/rust-parse-impl-expr.hxx
index bcfdd2d7a..a5a9c694a 100644
--- a/gcc/rust/parse/rust-parse-impl-expr.hxx
+++ b/gcc/rust/parse/rust-parse-impl-expr.hxx
@@ -687,9 +687,9 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec 
outer_attrs,
   lexer.skip_token ();
 
   // parse match arm patterns (which are required)
-  std::vector<std::unique_ptr<AST::Pattern>> match_arm_patterns
-    = parse_match_arm_patterns (EQUAL);
-  if (match_arm_patterns.empty ())
+  std::unique_ptr<AST::Pattern> match_arm_pattern
+    = parse_match_arm_pattern (EQUAL);
+  if (match_arm_pattern == nullptr)
     {
       Error error (
        lexer.peek_token ()->get_locus (),
@@ -740,7 +740,7 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec 
outer_attrs,
     {
       // single selection - end of if let expression
       return std::unique_ptr<AST::IfLetExpr> (
-       new AST::IfLetExpr (std::move (match_arm_patterns),
+       new AST::IfLetExpr (std::move (match_arm_pattern),
                            std::move (scrutinee_expr), std::move (if_let_body),
                            std::move (outer_attrs), locus));
     }
@@ -772,7 +772,7 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec 
outer_attrs,
              }
 
            return std::unique_ptr<AST::IfLetExprConseqElse> (
-             new AST::IfLetExprConseqElse (std::move (match_arm_patterns),
+             new AST::IfLetExprConseqElse (std::move (match_arm_pattern),
                                            std::move (scrutinee_expr),
                                            std::move (if_let_body),
                                            std::move (else_body),
@@ -800,7 +800,7 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec 
outer_attrs,
 
                return std::unique_ptr<AST::IfLetExprConseqElse> (
                  new AST::IfLetExprConseqElse (
-                   std::move (match_arm_patterns), std::move (scrutinee_expr),
+                   std::move (match_arm_pattern), std::move (scrutinee_expr),
                    std::move (if_let_body), std::move (if_let_expr),
                    std::move (outer_attrs), locus));
              }
@@ -821,7 +821,7 @@ Parser<ManagedTokenSource>::parse_if_let_expr (AST::AttrVec 
outer_attrs,
 
                return std::unique_ptr<AST::IfLetExprConseqElse> (
                  new AST::IfLetExprConseqElse (
-                   std::move (match_arm_patterns), std::move (scrutinee_expr),
+                   std::move (match_arm_pattern), std::move (scrutinee_expr),
                    std::move (if_let_body), std::move (if_expr),
                    std::move (outer_attrs), locus));
              }
@@ -983,10 +983,10 @@ Parser<ManagedTokenSource>::parse_while_let_loop_expr (
   lexer.skip_token ();
 
   // parse predicate patterns
-  std::vector<std::unique_ptr<AST::Pattern>> predicate_patterns
-    = parse_match_arm_patterns (EQUAL);
+  std::unique_ptr<AST::Pattern> predicate_pattern
+    = parse_match_arm_pattern (EQUAL);
   // ensure that there is at least 1 pattern
-  if (predicate_patterns.empty ())
+  if (predicate_pattern == nullptr)
     {
       Error error (lexer.peek_token ()->get_locus (),
                   "should be at least 1 pattern");
@@ -1030,8 +1030,8 @@ Parser<ManagedTokenSource>::parse_while_let_loop_expr (
     }
 
   return std::unique_ptr<AST::WhileLetLoopExpr> (new AST::WhileLetLoopExpr (
-    std::move (predicate_patterns), std::move (predicate_expr),
-    std::move (body), locus, std::move (label), std::move (outer_attrs)));
+    std::move (predicate_pattern), std::move (predicate_expr), std::move 
(body),
+    locus, std::move (label), std::move (outer_attrs)));
 }
 
 /* Parses a "for" iterative loop. Label is not parsed and should be parsed via
diff --git a/gcc/rust/parse/rust-parse-impl.hxx 
b/gcc/rust/parse/rust-parse-impl.hxx
index 4ad4f8343..48bd7cc65 100644
--- a/gcc/rust/parse/rust-parse-impl.hxx
+++ b/gcc/rust/parse/rust-parse-impl.hxx
@@ -5423,9 +5423,9 @@ Parser<ManagedTokenSource>::parse_match_arm ()
     }
 
   // parse match arm patterns - at least 1 is required
-  std::vector<std::unique_ptr<AST::Pattern>> match_arm_patterns
-    = parse_match_arm_patterns (RIGHT_CURLY);
-  if (match_arm_patterns.empty ())
+  std::unique_ptr<AST::Pattern> match_arm_pattern
+    = parse_match_arm_pattern (RIGHT_CURLY);
+  if (match_arm_pattern == nullptr)
     {
       Error error (lexer.peek_token ()->get_locus (),
                   "failed to parse any patterns in match arm");
@@ -5459,7 +5459,7 @@ Parser<ManagedTokenSource>::parse_match_arm ()
   // DEBUG
   rust_debug ("successfully parsed match arm");
 
-  return AST::MatchArm (std::move (match_arm_patterns),
+  return AST::MatchArm (std::move (match_arm_pattern),
                        lexer.peek_token ()->get_locus (),
                        std::move (guard_expr), std::move (outer_attrs));
 }
@@ -5468,8 +5468,8 @@ Parser<ManagedTokenSource>::parse_match_arm ()
  * token that would exist after the patterns are done (e.g. '}' for match
  * expr, '=' for if let and while let). */
 template <typename ManagedTokenSource>
-std::vector<std::unique_ptr<AST::Pattern>>
-Parser<ManagedTokenSource>::parse_match_arm_patterns (TokenId end_token_id)
+std::unique_ptr<AST::Pattern>
+Parser<ManagedTokenSource>::parse_match_arm_pattern (TokenId end_token_id)
 {
   // skip optional leading '|'
   if (lexer.peek_token ()->get_id () == PIPE)
@@ -5478,56 +5478,21 @@ Parser<ManagedTokenSource>::parse_match_arm_patterns 
(TokenId end_token_id)
    * If semantically different, I need a wrapped "match arm patterns" object
    * for this. */
 
-  std::vector<std::unique_ptr<AST::Pattern>> patterns;
+  std::unique_ptr<AST::Pattern> pattern;
 
   // quick break out if end_token_id
   if (lexer.peek_token ()->get_id () == end_token_id)
-    return patterns;
+    return pattern;
 
   // parse required pattern - if doesn't exist, return empty
   std::unique_ptr<AST::Pattern> initial_pattern = parse_pattern ();
   if (initial_pattern == nullptr)
     {
       // FIXME: should this be an error?
-      return patterns;
+      return pattern;
     }
-  patterns.push_back (std::move (initial_pattern));
 
-  // DEBUG
-  rust_debug ("successfully parsed initial match arm pattern");
-
-  // parse new patterns as long as next char is '|'
-  const_TokenPtr t = lexer.peek_token ();
-  while (t->get_id () == PIPE)
-    {
-      // skip pipe token
-      lexer.skip_token ();
-
-      // break if hit end token id
-      if (lexer.peek_token ()->get_id () == end_token_id)
-       break;
-
-      // parse pattern
-      std::unique_ptr<AST::Pattern> pattern = parse_pattern ();
-      if (pattern == nullptr)
-       {
-         // this is an error
-         Error error (lexer.peek_token ()->get_locus (),
-                      "failed to parse pattern in match arm patterns");
-         add_error (std::move (error));
-
-         // skip somewhere?
-         return {};
-       }
-
-      patterns.push_back (std::move (pattern));
-
-      t = lexer.peek_token ();
-    }
-
-  patterns.shrink_to_fit ();
-
-  return patterns;
+  return initial_pattern;
 }
 
 // Parses a single parameter used in a closure definition.
diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h
index 27c818543..9e6d4bc21 100644
--- a/gcc/rust/parse/rust-parse.h
+++ b/gcc/rust/parse/rust-parse.h
@@ -748,8 +748,7 @@ private:
   parse_match_expr (AST::AttrVec outer_attrs = AST::AttrVec (),
                    location_t pratt_parsed_loc = UNKNOWN_LOCATION);
   AST::MatchArm parse_match_arm ();
-  std::vector<std::unique_ptr<AST::Pattern>>
-  parse_match_arm_patterns (TokenId end_token_id);
+  std::unique_ptr<AST::Pattern> parse_match_arm_pattern (TokenId end_token_id);
   std::unique_ptr<AST::Expr> parse_labelled_loop_expr (const_TokenPtr tok,
                                                       AST::AttrVec outer_attrs
                                                       = AST::AttrVec ());
diff --git a/gcc/rust/resolve/rust-default-resolver.cc 
b/gcc/rust/resolve/rust-default-resolver.cc
index f1c0e5caf..434f4c945 100644
--- a/gcc/rust/resolve/rust-default-resolver.cc
+++ b/gcc/rust/resolve/rust-default-resolver.cc
@@ -91,8 +91,7 @@ DefaultResolver::visit (AST::ForLoopExpr &expr)
 void
 DefaultResolver::visit_if_let_patterns (AST::IfLetExpr &expr)
 {
-  for (auto &pattern : expr.get_patterns ())
-    visit (pattern);
+  visit (expr.get_pattern ());
 }
 
 void
diff --git a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc 
b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
index 3a1ff475f..2b156013a 100644
--- a/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
+++ b/gcc/rust/resolve/rust-late-name-resolver-2.0.cc
@@ -93,8 +93,7 @@ Late::visit (AST::MatchArm &arm)
 
   ctx.bindings.enter (BindingSource::Match);
 
-  for (auto &pattern : arm.get_patterns ())
-    visit (pattern);
+  visit (arm.get_pattern ());
 
   ctx.bindings.exit ();
 
@@ -153,8 +152,7 @@ Late::visit (AST::WhileLetLoopExpr &while_let)
 
   ctx.bindings.enter (BindingSource::WhileLet);
 
-  for (auto &pattern : while_let.get_patterns ())
-    visit (pattern);
+  visit (while_let.get_pattern ());
 
   ctx.bindings.exit ();
 
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.cc 
b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
index 0188ceae0..1466b8f09 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.cc
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.cc
@@ -1744,27 +1744,25 @@ TypeCheckExpr::visit (HIR::MatchExpr &expr)
     {
       // lets check the arms
       HIR::MatchArm &kase_arm = kase.get_arm ();
-      for (auto &pattern : kase_arm.get_patterns ())
+      auto &pattern = kase_arm.get_pattern ();
+      TyTy::BaseType *kase_arm_ty
+       = TypeCheckPattern::Resolve (*pattern, scrutinee_tyty);
+      if (kase_arm_ty->get_kind () == TyTy ::TypeKind::ERROR)
        {
-         TyTy::BaseType *kase_arm_ty
-           = TypeCheckPattern::Resolve (*pattern, scrutinee_tyty);
-         if (kase_arm_ty->get_kind () == TyTy ::TypeKind::ERROR)
-           {
-             saw_error = true;
-             continue;
-           }
+         saw_error = true;
+         continue;
+       }
 
-         TyTy::BaseType *checked_kase = unify_site (
-           expr.get_mappings ().get_hirid (),
-           TyTy::TyWithLocation (scrutinee_tyty,
-                                 expr.get_scrutinee_expr ().get_locus ()),
-           TyTy::TyWithLocation (kase_arm_ty, pattern->get_locus ()),
-           expr.get_locus ());
-         if (checked_kase->get_kind () == TyTy::TypeKind::ERROR)
-           {
-             saw_error = true;
-             continue;
-           }
+      TyTy::BaseType *checked_kase = unify_site (
+       expr.get_mappings ().get_hirid (),
+       TyTy::TyWithLocation (scrutinee_tyty,
+                             expr.get_scrutinee_expr ().get_locus ()),
+       TyTy::TyWithLocation (kase_arm_ty, pattern->get_locus ()),
+       expr.get_locus ());
+      if (checked_kase->get_kind () == TyTy::TypeKind::ERROR)
+       {
+         saw_error = true;
+         continue;
        }
 
       // check the kase type

base-commit: 11c436c6270c51b978a0ead489658e1b77ab1588
-- 
2.52.0

Reply via email to