public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc/devel/rust/master] Revert desugaring of CompoundAssignment into arithmetic operation and assignment
@ 2022-06-08 11:51 Thomas Schwinge
  0 siblings, 0 replies; only message in thread
From: Thomas Schwinge @ 2022-06-08 11:51 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:432add899f4e436d0d30b89ef87fe19e71b36955

commit 432add899f4e436d0d30b89ef87fe19e71b36955
Author: Philip Herron <philip.herron@embecosm.com>
Date:   Mon Nov 8 00:57:51 2021 +0000

    Revert desugaring of CompoundAssignment into arithmetic operation and assignment

Diff:
---
 gcc/rust/backend/rust-compile-expr.h          | 17 ++++++
 gcc/rust/hir/rust-ast-lower-expr.h            | 16 ++----
 gcc/rust/hir/tree/rust-hir-expr.h             | 74 +++++++++++++++++++++++++++
 gcc/rust/hir/tree/rust-hir-full-test.cc       | 67 ++++++++++++++++++++++++
 gcc/rust/hir/tree/rust-hir-visitor.h          |  1 +
 gcc/rust/lint/rust-lint-marklive-base.h       |  2 +-
 gcc/rust/lint/rust-lint-marklive.h            |  6 +++
 gcc/rust/typecheck/rust-hir-const-fold-base.h |  2 +-
 gcc/rust/typecheck/rust-hir-type-check-base.h |  2 +-
 gcc/rust/typecheck/rust-hir-type-check-expr.h | 23 +++++++++
 gcc/rust/typecheck/rust-hir-type-check-util.h |  2 +-
 11 files changed, 196 insertions(+), 16 deletions(-)

diff --git a/gcc/rust/backend/rust-compile-expr.h b/gcc/rust/backend/rust-compile-expr.h
index c9d3c304aab..8ed84c79086 100644
--- a/gcc/rust/backend/rust-compile-expr.h
+++ b/gcc/rust/backend/rust-compile-expr.h
@@ -388,6 +388,23 @@ public:
     ctx->add_statement (assignment);
   }
 
+  void visit (HIR::CompoundAssignmentExpr &expr) override
+  {
+    fncontext fn = ctx->peek_fn ();
+    auto lvalue = CompileExpr::Compile (expr.get_left_expr ().get (), ctx);
+    auto rvalue = CompileExpr::Compile (expr.get_right_expr ().get (), ctx);
+
+    auto op = expr.get_expr_type ();
+    auto operator_expr = ctx->get_backend ()->arithmetic_or_logical_expression (
+      op, lvalue, rvalue, expr.get_locus ());
+
+    Bstatement *assignment
+      = ctx->get_backend ()->assignment_statement (fn.fndecl, lvalue,
+						   operator_expr,
+						   expr.get_locus ());
+    ctx->add_statement (assignment);
+  }
+
   void visit (HIR::ArrayIndexExpr &expr) override
   {
     Bexpression *array = CompileExpr::Compile (expr.get_array_expr (), ctx);
diff --git a/gcc/rust/hir/rust-ast-lower-expr.h b/gcc/rust/hir/rust-ast-lower-expr.h
index 54cb6113ab7..f36096b44ef 100644
--- a/gcc/rust/hir/rust-ast-lower-expr.h
+++ b/gcc/rust/hir/rust-ast-lower-expr.h
@@ -452,11 +452,8 @@ public:
 			       expr.get_locus ());
   }
 
-  /* Compound assignment expression is compiled away. */
   void visit (AST::CompoundAssignmentExpr &expr) override
   {
-    /* First we need to find the corresponding arithmetic or logical operator.
-     */
     ArithmeticOrLogicalOperator op;
     switch (expr.get_expr_type ())
       {
@@ -503,15 +500,10 @@ public:
     Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
 				   mappings->get_next_hir_id (crate_num),
 				   UNKNOWN_LOCAL_DEFID);
-    HIR::Expr *operator_expr
-      = new HIR::ArithmeticOrLogicalExpr (mapping, asignee_expr->clone_expr (),
-					  std::unique_ptr<HIR::Expr> (value),
-					  op, expr.get_locus ());
-    translated
-      = new HIR::AssignmentExpr (mapping,
-				 std::unique_ptr<HIR::Expr> (asignee_expr),
-				 std::unique_ptr<HIR::Expr> (operator_expr),
-				 expr.get_locus ());
+
+    translated = new HIR::CompoundAssignmentExpr (
+      mapping, std::unique_ptr<HIR::Expr> (asignee_expr),
+      std::unique_ptr<HIR::Expr> (value), op, expr.get_locus ());
   }
 
   void visit (AST::StructExprStruct &struct_expr) override
diff --git a/gcc/rust/hir/tree/rust-hir-expr.h b/gcc/rust/hir/tree/rust-hir-expr.h
index 37ec15d8992..901feda5e31 100644
--- a/gcc/rust/hir/tree/rust-hir-expr.h
+++ b/gcc/rust/hir/tree/rust-hir-expr.h
@@ -666,6 +666,80 @@ protected:
   }
 };
 
+class CompoundAssignmentExpr : public OperatorExpr
+{
+public:
+  using ExprType = ArithmeticOrLogicalOperator;
+
+private:
+  // Note: overloading trait specified in comments
+  ExprType expr_type;
+  std::unique_ptr<Expr> right_expr;
+
+public:
+  std::string as_string () const override;
+
+  ExprType get_expr_type () const { return expr_type; }
+
+  // Use pointers in constructor to enable polymorphism
+  CompoundAssignmentExpr (Analysis::NodeMapping mappings,
+			  std::unique_ptr<Expr> value_to_assign_to,
+			  std::unique_ptr<Expr> value_to_assign,
+			  ExprType expr_kind, Location locus)
+    : OperatorExpr (std::move (mappings), std::move (value_to_assign_to),
+		    AST::AttrVec (), locus),
+      expr_type (expr_kind), right_expr (std::move (value_to_assign))
+  {}
+  // outer attributes not allowed
+
+  // Have clone in copy constructor
+  CompoundAssignmentExpr (CompoundAssignmentExpr const &other)
+    : OperatorExpr (other), expr_type (other.expr_type),
+      right_expr (other.right_expr->clone_expr ())
+  {}
+
+  // Overload assignment operator to clone
+  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;
+  }
+
+  // move constructors
+  CompoundAssignmentExpr (CompoundAssignmentExpr &&other) = default;
+  CompoundAssignmentExpr &operator= (CompoundAssignmentExpr &&other) = default;
+
+  void accept_vis (HIRVisitor &vis) override;
+
+  std::unique_ptr<Expr> &get_left_expr ()
+  {
+    rust_assert (main_or_left_expr != nullptr);
+    return main_or_left_expr;
+  }
+
+  std::unique_ptr<Expr> &get_right_expr ()
+  {
+    rust_assert (right_expr != nullptr);
+    return right_expr;
+  }
+
+  void visit_lhs (HIRVisitor &vis) { main_or_left_expr->accept_vis (vis); }
+  void visit_rhs (HIRVisitor &vis) { right_expr->accept_vis (vis); }
+
+protected:
+  /* Use covariance to implement clone function as returning this object rather
+   * than base */
+  CompoundAssignmentExpr *clone_expr_without_block_impl () const override
+  {
+    return new CompoundAssignmentExpr (*this);
+  }
+};
+
 // Expression in parentheses (i.e. like literally just any 3 + (2 * 6))
 class GroupedExpr : public ExprWithoutBlock
 {
diff --git a/gcc/rust/hir/tree/rust-hir-full-test.cc b/gcc/rust/hir/tree/rust-hir-full-test.cc
index bacef82ab3e..843e32ca1af 100644
--- a/gcc/rust/hir/tree/rust-hir-full-test.cc
+++ b/gcc/rust/hir/tree/rust-hir-full-test.cc
@@ -1315,6 +1315,67 @@ AssignmentExpr::as_string () const
 	 + "::" + get_mappings ().as_string ();
 }
 
+std::string
+CompoundAssignmentExpr::as_string () const
+{
+  std::string operator_str;
+  operator_str.reserve (1);
+
+  // get operator string
+  switch (expr_type)
+    {
+    case ArithmeticOrLogicalOperator::ADD:
+      operator_str = "+";
+      break;
+    case ArithmeticOrLogicalOperator::SUBTRACT:
+      operator_str = "-";
+      break;
+    case ArithmeticOrLogicalOperator::MULTIPLY:
+      operator_str = "*";
+      break;
+    case ArithmeticOrLogicalOperator::DIVIDE:
+      operator_str = "/";
+      break;
+    case ArithmeticOrLogicalOperator::MODULUS:
+      operator_str = "%";
+      break;
+    case ArithmeticOrLogicalOperator::BITWISE_AND:
+      operator_str = "&";
+      break;
+    case ArithmeticOrLogicalOperator::BITWISE_OR:
+      operator_str = "|";
+      break;
+    case ArithmeticOrLogicalOperator::BITWISE_XOR:
+      operator_str = "^";
+      break;
+    case ArithmeticOrLogicalOperator::LEFT_SHIFT:
+      operator_str = "<<";
+      break;
+    case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
+      operator_str = ">>";
+      break;
+    default:
+      gcc_unreachable ();
+      break;
+    }
+
+  operator_str += "=";
+
+  std::string str ("CompoundAssignmentExpr: ");
+  if (main_or_left_expr == nullptr || right_expr == nullptr)
+    {
+      str += "error. this is probably a parsing failure.";
+    }
+  else
+    {
+      str += "\n left: " + main_or_left_expr->as_string ();
+      str += "\n right: " + right_expr->as_string ();
+      str += "\n operator: " + operator_str;
+    }
+
+  return str;
+}
+
 std::string
 AsyncBlockExpr::as_string () const
 {
@@ -3818,6 +3879,12 @@ AssignmentExpr::accept_vis (HIRVisitor &vis)
   vis.visit (*this);
 }
 
+void
+CompoundAssignmentExpr::accept_vis (HIRVisitor &vis)
+{
+  vis.visit (*this);
+}
+
 void
 GroupedExpr::accept_vis (HIRVisitor &vis)
 {
diff --git a/gcc/rust/hir/tree/rust-hir-visitor.h b/gcc/rust/hir/tree/rust-hir-visitor.h
index 04874468cf1..ea125d9d082 100644
--- a/gcc/rust/hir/tree/rust-hir-visitor.h
+++ b/gcc/rust/hir/tree/rust-hir-visitor.h
@@ -47,6 +47,7 @@ public:
   virtual void visit (LazyBooleanExpr &expr) = 0;
   virtual void visit (TypeCastExpr &expr) = 0;
   virtual void visit (AssignmentExpr &expr) = 0;
+  virtual void visit (CompoundAssignmentExpr &expr) = 0;
   virtual void visit (GroupedExpr &expr) = 0;
   virtual void visit (ArrayElemsValues &elems) = 0;
   virtual void visit (ArrayElemsCopied &elems) = 0;
diff --git a/gcc/rust/lint/rust-lint-marklive-base.h b/gcc/rust/lint/rust-lint-marklive-base.h
index b67705bebab..e0494d702eb 100644
--- a/gcc/rust/lint/rust-lint-marklive-base.h
+++ b/gcc/rust/lint/rust-lint-marklive-base.h
@@ -53,7 +53,7 @@ public:
   virtual void visit (HIR::LazyBooleanExpr &) override {}
   virtual void visit (HIR::TypeCastExpr &) override {}
   virtual void visit (HIR::AssignmentExpr &) override {}
-
+  virtual void visit (HIR::CompoundAssignmentExpr &) override {}
   virtual void visit (HIR::GroupedExpr &) override {}
 
   virtual void visit (HIR::ArrayElemsValues &) override {}
diff --git a/gcc/rust/lint/rust-lint-marklive.h b/gcc/rust/lint/rust-lint-marklive.h
index ca5d8945c29..bcf792b9862 100644
--- a/gcc/rust/lint/rust-lint-marklive.h
+++ b/gcc/rust/lint/rust-lint-marklive.h
@@ -186,6 +186,12 @@ public:
     expr.visit_rhs (*this);
   }
 
+  void visit (HIR::CompoundAssignmentExpr &expr) override
+  {
+    expr.visit_lhs (*this);
+    expr.visit_rhs (*this);
+  }
+
   void visit (HIR::IfExpr &expr) override
   {
     expr.get_if_condition ()->accept_vis (*this);
diff --git a/gcc/rust/typecheck/rust-hir-const-fold-base.h b/gcc/rust/typecheck/rust-hir-const-fold-base.h
index 9cbf1ab2df7..0b410532424 100644
--- a/gcc/rust/typecheck/rust-hir-const-fold-base.h
+++ b/gcc/rust/typecheck/rust-hir-const-fold-base.h
@@ -56,7 +56,7 @@ public:
   virtual void visit (HIR::LazyBooleanExpr &) override {}
   virtual void visit (HIR::TypeCastExpr &) override {}
   virtual void visit (HIR::AssignmentExpr &) override {}
-
+  virtual void visit (HIR::CompoundAssignmentExpr &) override {}
   virtual void visit (HIR::GroupedExpr &) override {}
 
   virtual void visit (HIR::ArrayElemsValues &) override {}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-base.h b/gcc/rust/typecheck/rust-hir-type-check-base.h
index eb96fd18e02..52dea212170 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-base.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-base.h
@@ -58,7 +58,7 @@ public:
   virtual void visit (HIR::LazyBooleanExpr &) override {}
   virtual void visit (HIR::TypeCastExpr &) override {}
   virtual void visit (HIR::AssignmentExpr &) override {}
-
+  virtual void visit (HIR::CompoundAssignmentExpr &) override {}
   virtual void visit (HIR::GroupedExpr &) override {}
 
   virtual void visit (HIR::ArrayElemsValues &) override {}
diff --git a/gcc/rust/typecheck/rust-hir-type-check-expr.h b/gcc/rust/typecheck/rust-hir-type-check-expr.h
index b332a684ad4..2594a415d78 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-expr.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-expr.h
@@ -470,6 +470,29 @@ public:
       result->clone ());
   }
 
+  void visit (HIR::CompoundAssignmentExpr &expr) override
+  {
+    infered = new TyTy::TupleType (expr.get_mappings ().get_hirid ());
+
+    auto lhs = TypeCheckExpr::Resolve (expr.get_left_expr ().get (), false);
+    auto rhs = TypeCheckExpr::Resolve (expr.get_right_expr ().get (), false);
+
+    bool valid_lhs = validate_arithmetic_type (lhs, expr.get_expr_type ());
+    bool valid_rhs = validate_arithmetic_type (rhs, expr.get_expr_type ());
+    bool valid = valid_lhs && valid_rhs;
+    if (!valid)
+      {
+	rust_error_at (expr.get_locus (),
+		       "cannot apply this operator to types %s and %s",
+		       lhs->as_string ().c_str (), rhs->as_string ().c_str ());
+	return;
+      }
+
+    auto result = lhs->unify (rhs);
+    if (result->get_kind () == TyTy::TypeKind::ERROR)
+      return;
+  }
+
   void visit (HIR::IdentifierExpr &expr) override
   {
     NodeId ast_node_id = expr.get_mappings ().get_nodeid ();
diff --git a/gcc/rust/typecheck/rust-hir-type-check-util.h b/gcc/rust/typecheck/rust-hir-type-check-util.h
index 4595ca334b9..f078df6abd2 100644
--- a/gcc/rust/typecheck/rust-hir-type-check-util.h
+++ b/gcc/rust/typecheck/rust-hir-type-check-util.h
@@ -51,7 +51,7 @@ public:
   virtual void visit (HIR::LazyBooleanExpr &) override {}
   virtual void visit (HIR::TypeCastExpr &) override {}
   virtual void visit (HIR::AssignmentExpr &) override {}
-
+  virtual void visit (HIR::CompoundAssignmentExpr &) override {}
   virtual void visit (HIR::GroupedExpr &) override {}
 
   virtual void visit (HIR::ArrayElemsValues &) override {}


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

only message in thread, other threads:[~2022-06-08 11:51 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:51 [gcc/devel/rust/master] Revert desugaring of CompoundAssignment into arithmetic operation and assignment 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).