public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Add hir lowering for match-expr
@ 2022-06-08 11:56 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 11:56 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a688913ac153a85aa803faad9d243e66fd12889d

commit a688913ac153a85aa803faad9d243e66fd12889d
Author: Philip Herron <philip.herron@embecosm.com>
Date:   Wed Dec 15 01:06:52 2021 +0000

    Add hir lowering for match-expr

Diff:
---
 gcc/rust/Make-lang.in                   |   1 +
 gcc/rust/hir/rust-ast-lower-expr.h      |  51 ++++++++++++++
 gcc/rust/hir/rust-ast-lower-pattern.cc  | 115 ++++++++++++++++++++++++++++++++
 gcc/rust/hir/rust-ast-lower-pattern.h   |  12 ++--
 gcc/rust/hir/tree/rust-hir-expr.h       |  52 +++------------
 gcc/rust/hir/tree/rust-hir-full-decls.h |   1 -
 gcc/rust/hir/tree/rust-hir-full-test.cc |  10 ---
 gcc/rust/hir/tree/rust-hir-pattern.h    |  62 +----------------
 8 files changed, 187 insertions(+), 117 deletions(-)

diff --git a/gcc/rust/Make-lang.in b/gcc/rust/Make-lang.in
index a4054285bbd..1274578a714 100644
--- a/gcc/rust/Make-lang.in
+++ b/gcc/rust/Make-lang.in
@@ -76,6 +76,7 @@ GRS_OBJS = \
     rust/rust-hir-full-test.o \
     rust/rust-hir-map.o \
     rust/rust-ast-lower.o \
+    rust/rust-ast-lower-pattern.o \
     rust/rust-ast-resolve.o \
     rust/rust-ast-resolve-pattern.o \
     rust/rust-hir-type-check.o \
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index d6e21946d11..8cd4fb537d1 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -23,6 +23,7 @@
 #include "rust-ast-lower-base.h"
 #include "rust-ast-lower-block.h"
 #include "rust-ast-lower-struct-field-expr.h"
+#include "rust-ast-lower-pattern.h"
 
 namespace Rust {
 namespace HIR {
@@ -667,6 +668,56 @@ public:
 				  expr.get_outer_attrs (), expr.get_locus ());
   }
 
+  void visit (AST::MatchExpr &expr) override
+  {
+    HIR::Expr *branch_value
+      = ASTLoweringExpr::translate (expr.get_scrutinee_expr ().get ());
+
+    std::vector<HIR::MatchCase> match_arms;
+    for (auto &match_case : expr.get_match_cases ())
+      {
+	HIR::Expr *kase_expr
+	  = ASTLoweringExpr::translate (match_case.get_expr ().get ());
+
+	HIR::Expr *kase_guard_expr = nullptr;
+	if (match_case.get_arm ().has_match_arm_guard ())
+	  {
+	    kase_guard_expr = ASTLoweringExpr::translate (
+	      match_case.get_arm ().get_guard_expr ().get ());
+	  }
+
+	std::vector<std::unique_ptr<HIR::Pattern> > match_arm_patterns;
+	for (auto &pattern : match_case.get_arm ().get_patterns ())
+	  {
+	    HIR::Pattern *ptrn = ASTLoweringPattern::translate (pattern.get ());
+	    match_arm_patterns.push_back (std::unique_ptr<HIR::Pattern> (ptrn));
+	  }
+
+	HIR::MatchArm arm (std::move (match_arm_patterns),
+			   std::unique_ptr<HIR::Expr> (kase_guard_expr),
+			   match_case.get_arm ().get_outer_attrs ());
+
+	auto crate_num = mappings->get_current_crate ();
+	Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				       mappings->get_next_hir_id (crate_num),
+				       UNKNOWN_LOCAL_DEFID);
+
+	HIR::MatchCase kase (std::move (mapping), std::move (arm),
+			     std::unique_ptr<HIR::Expr> (kase_expr));
+	match_arms.push_back (std::move (kase));
+      }
+
+    auto crate_num = mappings->get_current_crate ();
+    Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
+				   mappings->get_next_hir_id (crate_num),
+				   UNKNOWN_LOCAL_DEFID);
+
+    translated
+      = new HIR::MatchExpr (mapping, std::unique_ptr<HIR::Expr> (branch_value),
+			    std::move (match_arms), expr.get_inner_attrs (),
+			    expr.get_outer_attrs (), expr.get_locus ());
+  }
+
 private:
   ASTLoweringExpr ()
     : ASTLoweringBase (), translated (nullptr),
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.cc b/gcc/rust/hir/rust-ast-lower-pattern.cc
new file mode 100644
index 00000000000..4ff61cd2a47
--- /dev/null
+++ b/gcc/rust/hir/rust-ast-lower-pattern.cc
@@ -0,0 +1,115 @@
+// Copyright (C) 2020-2021 Free Software Foundation, Inc.
+
+// This file is part of GCC.
+
+// GCC is free software; you can redistribute it and/or modify it under
+// the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3, or (at your option) any later
+// version.
+
+// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+// for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with GCC; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include "rust-ast-lower-pattern.h"
+#include "rust-ast-lower-expr.h"
+
+namespace Rust {
+namespace HIR {
+
+void
+ASTLoweringPattern::visit (AST::PathInExpression &pattern)
+{
+  translated = ASTLowerPathInExpression::translate (&pattern);
+}
+
+void
+ASTLoweringPattern::visit (AST::TupleStructPattern &pattern)
+{
+  HIR::PathInExpression *path
+    = ASTLowerPathInExpression::translate (&pattern.get_path ());
+
+  TupleStructItems *lowered = nullptr;
+  auto &items = pattern.get_items ();
+  switch (items->get_item_type ())
+    {
+      case AST::TupleStructItems::RANGE: {
+	// TODO
+	gcc_unreachable ();
+      }
+      break;
+
+      case AST::TupleStructItems::NO_RANGE: {
+	AST::TupleStructItemsNoRange &items_no_range
+	  = static_cast<AST::TupleStructItemsNoRange &> (*items.get ());
+
+	std::vector<std::unique_ptr<HIR::Pattern> > patterns;
+	for (auto &inner_pattern : items_no_range.get_patterns ())
+	  {
+	    HIR::Pattern *p
+	      = ASTLoweringPattern::translate (inner_pattern.get ());
+	    patterns.push_back (std::unique_ptr<HIR::Pattern> (p));
+	  }
+
+	lowered = new HIR::TupleStructItemsNoRange (std::move (patterns));
+      }
+      break;
+    }
+
+  translated = new HIR::TupleStructPattern (
+    *path, std::unique_ptr<HIR::TupleStructItems> (lowered));
+}
+
+void
+ASTLoweringPattern::visit (AST::StructPattern &pattern)
+{
+  HIR::PathInExpression *path
+    = ASTLowerPathInExpression::translate (&pattern.get_path ());
+
+  auto &raw_elems = pattern.get_struct_pattern_elems ();
+  rust_assert (!raw_elems.has_etc ());
+
+  std::vector<std::unique_ptr<HIR::StructPatternField> > fields;
+  for (auto &field : raw_elems.get_struct_pattern_fields ())
+    {
+      HIR::StructPatternField *f = nullptr;
+      switch (field->get_item_type ())
+	{
+	  case AST::StructPatternField::ItemType::TUPLE_PAT: {
+	    // TODO
+	    gcc_unreachable ();
+	  }
+	  break;
+
+	  case AST::StructPatternField::ItemType::IDENT_PAT: {
+	    // TODO
+	    gcc_unreachable ();
+	  }
+	  break;
+
+	  case AST::StructPatternField::ItemType::IDENT: {
+	    AST::StructPatternFieldIdent &ident
+	      = static_cast<AST::StructPatternFieldIdent &> (*field.get ());
+
+	    f = new HIR::StructPatternFieldIdent (
+	      ident.get_identifier (), ident.is_ref (),
+	      ident.is_mut () ? Mutability::Mut : Mutability::Imm,
+	      ident.get_outer_attrs (), ident.get_locus ());
+	  }
+	  break;
+	}
+
+      fields.push_back (std::unique_ptr<HIR::StructPatternField> (f));
+    }
+
+  HIR::StructPatternElements elems (std::move (fields));
+  translated = new HIR::StructPattern (*path, std::move (elems));
+}
+
+} // namespace HIR
+} // namespace Rust
diff --git a/gcc/rust/hir/rust-ast-lower-pattern.h b/gcc/rust/hir/rust-ast-lower-pattern.h
index d7b6a47e3bb..d8c03cef744 100644
--- a/gcc/rust/hir/rust-ast-lower-pattern.h
+++ b/gcc/rust/hir/rust-ast-lower-pattern.h
@@ -20,7 +20,6 @@
 #define RUST_AST_LOWER_PATTERN
 
 #include "rust-ast-lower-base.h"
-#include "rust-diagnostics.h"
 
 namespace Rust {
 namespace HIR {
@@ -34,12 +33,11 @@ public:
   {
     ASTLoweringPattern resolver;
     pattern->accept_vis (resolver);
+    rust_assert (resolver.translated != nullptr);
     return resolver.translated;
   }
 
-  virtual ~ASTLoweringPattern () override {}
-
-  void visit (AST::IdentifierPattern &pattern)
+  void visit (AST::IdentifierPattern &pattern) override
   {
     std::unique_ptr<Pattern> to_bind;
     translated
@@ -50,6 +48,12 @@ public:
 				    std::move (to_bind));
   }
 
+  void visit (AST::PathInExpression &pattern) override;
+
+  void visit (AST::StructPattern &pattern) override;
+
+  void visit (AST::TupleStructPattern &pattern) override;
+
 private:
   ASTLoweringPattern () : translated (nullptr) {}
 
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 901feda5e31..0e5d97b5c53 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -3681,57 +3681,29 @@ public:
   std::string as_string () const;
 };
 
-/*
-// Base "match case" for a match expression - abstract
-class MatchCase
-{
-  MatchArm arm;
-
-protected:
-  MatchCase (MatchArm arm) : arm (std::move (arm)) {}
-
-  // Should not require copy constructor or assignment operator overloading
-
-  // Clone function implementation as pure virtual method
-  virtual MatchCase *clone_match_case_impl () const = 0;
-
-public:
-  virtual ~MatchCase () {}
-
-  // Unique pointer custom clone function
-  std::unique_ptr<MatchCase> clone_match_case () const
-  {
-    return std::unique_ptr<MatchCase> (clone_match_case_impl ());
-  }
-
-  virtual std::string as_string () const;
-
-  virtual void accept_vis (HIRVisitor &vis) = 0;
-};
-*/
-
 /* A "match case" - a correlated match arm and resulting expression. Not
  * abstract. */
 struct MatchCase
 {
 private:
+  Analysis::NodeMapping mappings;
   MatchArm arm;
   std::unique_ptr<Expr> expr;
 
-  /* TODO: does whether trailing comma exists need to be stored? currently
-   * assuming it is only syntactical and has no effect on meaning. */
-
 public:
-  MatchCase (MatchArm arm, std::unique_ptr<Expr> expr)
-    : arm (std::move (arm)), expr (std::move (expr))
+  MatchCase (Analysis::NodeMapping mappings, MatchArm arm,
+	     std::unique_ptr<Expr> expr)
+    : mappings (mappings), arm (std::move (arm)), expr (std::move (expr))
   {}
 
   MatchCase (const MatchCase &other)
-    : arm (other.arm), expr (other.expr->clone_expr ())
+    : mappings (other.mappings), arm (other.arm),
+      expr (other.expr->clone_expr ())
   {}
 
   MatchCase &operator= (const MatchCase &other)
   {
+    mappings = other.mappings;
     arm = other.arm;
     expr = other.expr->clone_expr ();
 
@@ -3744,6 +3716,8 @@ public:
   ~MatchCase () = default;
 
   std::string as_string () const;
+
+  Analysis::NodeMapping get_mappings () const { return mappings; }
 };
 
 #if 0
@@ -3841,23 +3815,15 @@ class MatchExpr : public ExprWithBlock
 {
   std::unique_ptr<Expr> branch_value;
   AST::AttrVec inner_attrs;
-
-  // bool has_match_arms;
-  // MatchArms match_arms;
-  // std::vector<std::unique_ptr<MatchCase> > match_arms; // inlined from
-  // MatchArms
   std::vector<MatchCase> match_arms;
-
   Location locus;
 
 public:
   std::string as_string () const override;
 
-  // Returns whether the match expression has any match arms.
   bool has_match_arms () const { return !match_arms.empty (); }
 
   MatchExpr (Analysis::NodeMapping mappings, std::unique_ptr<Expr> branch_value,
-	     // std::vector<std::unique_ptr<MatchCase> > match_arms,
 	     std::vector<MatchCase> match_arms, AST::AttrVec inner_attrs,
 	     AST::AttrVec outer_attrs, Location locus)
     : ExprWithBlock (std::move (mappings), std::move (outer_attrs)),
diff --git a/gcc/rust/hir/tree/rust-hir-full-decls.h b/gcc/rust/hir/tree/rust-hir-full-decls.h
index 3e9d8b24bef..79f3789cb5a 100644
--- a/gcc/rust/hir/tree/rust-hir-full-decls.h
+++ b/gcc/rust/hir/tree/rust-hir-full-decls.h
@@ -199,7 +199,6 @@ class StructPatternField;
 class StructPatternFieldTuplePat;
 class StructPatternFieldIdentPat;
 class StructPatternFieldIdent;
-struct StructPatternElements;
 class StructPattern;
 class TupleStructItems;
 class TupleStructItemsNoRange;
diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc
index 843e32ca1af..76b88255d9a 100644
--- a/gcc/rust/hir/tree/rust-hir-full-test.cc
+++ b/gcc/rust/hir/tree/rust-hir-full-test.cc
@@ -2575,16 +2575,6 @@ StructPatternElements::as_string () const
 	}
     }
 
-  str += "\n  Etc: ";
-  if (has_struct_pattern_etc)
-    {
-      str += "true";
-    }
-  else
-    {
-      str += "false";
-    }
-
   return str;
 }
 
diff --git a/gcc/rust/hir/tree/rust-hir-pattern.h b/gcc/rust/hir/tree/rust-hir-pattern.h
index 4f0bfe61518..1373cc7a491 100644
--- a/gcc/rust/hir/tree/rust-hir-pattern.h
+++ b/gcc/rust/hir/tree/rust-hir-pattern.h
@@ -377,26 +377,6 @@ protected:
   }
 };
 
-// aka StructPatternEtCetera; potential element in struct pattern
-struct StructPatternEtc
-{
-private:
-  AST::AttrVec outer_attrs;
-
-  // should this store location data?
-
-public:
-  StructPatternEtc (AST::AttrVec outer_attribs)
-    : outer_attrs (std::move (outer_attribs))
-  {}
-
-  // Creates an empty StructPatternEtc
-  static StructPatternEtc create_empty ()
-  {
-    return StructPatternEtc (AST::AttrVec ());
-  }
-};
-
 // Base class for a single field in a struct pattern - abstract
 class StructPatternField
 {
@@ -561,45 +541,24 @@ protected:
 struct StructPatternElements
 {
 private:
-  // bool has_struct_pattern_fields;
   std::vector<std::unique_ptr<StructPatternField> > fields;
 
-  bool has_struct_pattern_etc;
-  StructPatternEtc etc;
-
-  // must have at least one of the two and maybe both
-
-  // should this store location data?
-
 public:
   // Returns whether there are any struct pattern fields
   bool has_struct_pattern_fields () const { return !fields.empty (); }
 
   /* Returns whether the struct pattern elements is entirely empty (no fields,
    * no etc). */
-  bool is_empty () const
-  {
-    return !has_struct_pattern_fields () && !has_struct_pattern_etc;
-  }
+  bool is_empty () const { return !has_struct_pattern_fields (); }
 
   // Constructor for StructPatternElements with both (potentially)
-  StructPatternElements (
-    std::vector<std::unique_ptr<StructPatternField> > fields,
-    StructPatternEtc etc)
-    : fields (std::move (fields)), has_struct_pattern_etc (true),
-      etc (std::move (etc))
-  {}
-
-  // Constructor for StructPatternElements with no StructPatternEtc
   StructPatternElements (
     std::vector<std::unique_ptr<StructPatternField> > fields)
-    : fields (std::move (fields)), has_struct_pattern_etc (false),
-      etc (StructPatternEtc::create_empty ())
+    : fields (std::move (fields))
   {}
 
   // Copy constructor with vector clone
   StructPatternElements (StructPatternElements const &other)
-    : has_struct_pattern_etc (other.has_struct_pattern_etc), etc (other.etc)
   {
     fields.reserve (other.fields.size ());
     for (const auto &e : other.fields)
@@ -609,9 +568,6 @@ public:
   // Overloaded assignment operator with vector clone
   StructPatternElements &operator= (StructPatternElements const &other)
   {
-    etc = other.etc;
-    has_struct_pattern_etc = other.has_struct_pattern_etc;
-
     fields.reserve (other.fields.size ());
     for (const auto &e : other.fields)
       fields.push_back (e->clone_struct_pattern_field ());
@@ -637,27 +593,15 @@ public:
 class StructPattern : public Pattern
 {
   PathInExpression path;
-
-  // bool has_struct_pattern_elements;
   StructPatternElements elems;
 
-  // TODO: should this store location data? Accessor uses path location data.
-
 public:
   std::string as_string () const override;
 
-  // Constructs a struct pattern from specified StructPatternElements
-  StructPattern (PathInExpression struct_path,
-		 StructPatternElements elems
-		 = StructPatternElements::create_empty ())
+  StructPattern (PathInExpression struct_path, StructPatternElements elems)
     : path (std::move (struct_path)), elems (std::move (elems))
   {}
 
-  /* TODO: constructor to construct via elements included in
-   * StructPatternElements */
-
-  /* Returns whether struct pattern has any struct pattern elements (if not, it
-   * is empty). */
   bool has_struct_pattern_elems () const { return !elems.is_empty (); }
 
   Location get_locus () const { return path.get_locus (); }


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-06-08 11:56 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-08 11:56 [gcc/devel/rust/master] Add hir lowering for match-expr Thomas Schwinge

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).