Skip to content

Commit c4b11ff

Browse files
committed
Revert desugaring of CompoundAssignment into arithmetic operation and assignment
1 parent c7262f8 commit c4b11ff

11 files changed

+196
-16
lines changed

gcc/rust/backend/rust-compile-expr.h

+17
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,23 @@ class CompileExpr : public HIRCompileBase
388388
ctx->add_statement (assignment);
389389
}
390390

391+
void visit (HIR::CompoundAssignmentExpr &expr) override
392+
{
393+
fncontext fn = ctx->peek_fn ();
394+
auto lvalue = CompileExpr::Compile (expr.get_left_expr ().get (), ctx);
395+
auto rvalue = CompileExpr::Compile (expr.get_right_expr ().get (), ctx);
396+
397+
auto op = expr.get_expr_type ();
398+
auto operator_expr = ctx->get_backend ()->arithmetic_or_logical_expression (
399+
op, lvalue, rvalue, expr.get_locus ());
400+
401+
Bstatement *assignment
402+
= ctx->get_backend ()->assignment_statement (fn.fndecl, lvalue,
403+
operator_expr,
404+
expr.get_locus ());
405+
ctx->add_statement (assignment);
406+
}
407+
391408
void visit (HIR::ArrayIndexExpr &expr) override
392409
{
393410
Bexpression *array = CompileExpr::Compile (expr.get_array_expr (), ctx);

gcc/rust/hir/rust-ast-lower-expr.h

+4-12
Original file line numberDiff line numberDiff line change
@@ -452,11 +452,8 @@ class ASTLoweringExpr : public ASTLoweringBase
452452
expr.get_locus ());
453453
}
454454

455-
/* Compound assignment expression is compiled away. */
456455
void visit (AST::CompoundAssignmentExpr &expr) override
457456
{
458-
/* First we need to find the corresponding arithmetic or logical operator.
459-
*/
460457
ArithmeticOrLogicalOperator op;
461458
switch (expr.get_expr_type ())
462459
{
@@ -503,15 +500,10 @@ class ASTLoweringExpr : public ASTLoweringBase
503500
Analysis::NodeMapping mapping (crate_num, expr.get_node_id (),
504501
mappings->get_next_hir_id (crate_num),
505502
UNKNOWN_LOCAL_DEFID);
506-
HIR::Expr *operator_expr
507-
= new HIR::ArithmeticOrLogicalExpr (mapping, asignee_expr->clone_expr (),
508-
std::unique_ptr<HIR::Expr> (value),
509-
op, expr.get_locus ());
510-
translated
511-
= new HIR::AssignmentExpr (mapping,
512-
std::unique_ptr<HIR::Expr> (asignee_expr),
513-
std::unique_ptr<HIR::Expr> (operator_expr),
514-
expr.get_locus ());
503+
504+
translated = new HIR::CompoundAssignmentExpr (
505+
mapping, std::unique_ptr<HIR::Expr> (asignee_expr),
506+
std::unique_ptr<HIR::Expr> (value), op, expr.get_locus ());
515507
}
516508

517509
void visit (AST::StructExprStruct &struct_expr) override

gcc/rust/hir/tree/rust-hir-expr.h

+74
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,80 @@ class AssignmentExpr : public OperatorExpr
666666
}
667667
};
668668

669+
class CompoundAssignmentExpr : public OperatorExpr
670+
{
671+
public:
672+
using ExprType = ArithmeticOrLogicalOperator;
673+
674+
private:
675+
// Note: overloading trait specified in comments
676+
ExprType expr_type;
677+
std::unique_ptr<Expr> right_expr;
678+
679+
public:
680+
std::string as_string () const override;
681+
682+
ExprType get_expr_type () const { return expr_type; }
683+
684+
// Use pointers in constructor to enable polymorphism
685+
CompoundAssignmentExpr (Analysis::NodeMapping mappings,
686+
std::unique_ptr<Expr> value_to_assign_to,
687+
std::unique_ptr<Expr> value_to_assign,
688+
ExprType expr_kind, Location locus)
689+
: OperatorExpr (std::move (mappings), std::move (value_to_assign_to),
690+
AST::AttrVec (), locus),
691+
expr_type (expr_kind), right_expr (std::move (value_to_assign))
692+
{}
693+
// outer attributes not allowed
694+
695+
// Have clone in copy constructor
696+
CompoundAssignmentExpr (CompoundAssignmentExpr const &other)
697+
: OperatorExpr (other), expr_type (other.expr_type),
698+
right_expr (other.right_expr->clone_expr ())
699+
{}
700+
701+
// Overload assignment operator to clone
702+
CompoundAssignmentExpr &operator= (CompoundAssignmentExpr const &other)
703+
{
704+
OperatorExpr::operator= (other);
705+
// main_or_left_expr = other.main_or_left_expr->clone_expr();
706+
right_expr = other.right_expr->clone_expr ();
707+
expr_type = other.expr_type;
708+
// outer_attrs = other.outer_attrs;
709+
710+
return *this;
711+
}
712+
713+
// move constructors
714+
CompoundAssignmentExpr (CompoundAssignmentExpr &&other) = default;
715+
CompoundAssignmentExpr &operator= (CompoundAssignmentExpr &&other) = default;
716+
717+
void accept_vis (HIRVisitor &vis) override;
718+
719+
std::unique_ptr<Expr> &get_left_expr ()
720+
{
721+
rust_assert (main_or_left_expr != nullptr);
722+
return main_or_left_expr;
723+
}
724+
725+
std::unique_ptr<Expr> &get_right_expr ()
726+
{
727+
rust_assert (right_expr != nullptr);
728+
return right_expr;
729+
}
730+
731+
void visit_lhs (HIRVisitor &vis) { main_or_left_expr->accept_vis (vis); }
732+
void visit_rhs (HIRVisitor &vis) { right_expr->accept_vis (vis); }
733+
734+
protected:
735+
/* Use covariance to implement clone function as returning this object rather
736+
* than base */
737+
CompoundAssignmentExpr *clone_expr_without_block_impl () const override
738+
{
739+
return new CompoundAssignmentExpr (*this);
740+
}
741+
};
742+
669743
// Expression in parentheses (i.e. like literally just any 3 + (2 * 6))
670744
class GroupedExpr : public ExprWithoutBlock
671745
{

gcc/rust/hir/tree/rust-hir-full-test.cc

+67
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,67 @@ AssignmentExpr::as_string () const
13151315
+ "::" + get_mappings ().as_string ();
13161316
}
13171317

1318+
std::string
1319+
CompoundAssignmentExpr::as_string () const
1320+
{
1321+
std::string operator_str;
1322+
operator_str.reserve (1);
1323+
1324+
// get operator string
1325+
switch (expr_type)
1326+
{
1327+
case ArithmeticOrLogicalOperator::ADD:
1328+
operator_str = "+";
1329+
break;
1330+
case ArithmeticOrLogicalOperator::SUBTRACT:
1331+
operator_str = "-";
1332+
break;
1333+
case ArithmeticOrLogicalOperator::MULTIPLY:
1334+
operator_str = "*";
1335+
break;
1336+
case ArithmeticOrLogicalOperator::DIVIDE:
1337+
operator_str = "/";
1338+
break;
1339+
case ArithmeticOrLogicalOperator::MODULUS:
1340+
operator_str = "%";
1341+
break;
1342+
case ArithmeticOrLogicalOperator::BITWISE_AND:
1343+
operator_str = "&";
1344+
break;
1345+
case ArithmeticOrLogicalOperator::BITWISE_OR:
1346+
operator_str = "|";
1347+
break;
1348+
case ArithmeticOrLogicalOperator::BITWISE_XOR:
1349+
operator_str = "^";
1350+
break;
1351+
case ArithmeticOrLogicalOperator::LEFT_SHIFT:
1352+
operator_str = "<<";
1353+
break;
1354+
case ArithmeticOrLogicalOperator::RIGHT_SHIFT:
1355+
operator_str = ">>";
1356+
break;
1357+
default:
1358+
gcc_unreachable ();
1359+
break;
1360+
}
1361+
1362+
operator_str += "=";
1363+
1364+
std::string str ("CompoundAssignmentExpr: ");
1365+
if (main_or_left_expr == nullptr || right_expr == nullptr)
1366+
{
1367+
str += "error. this is probably a parsing failure.";
1368+
}
1369+
else
1370+
{
1371+
str += "\n left: " + main_or_left_expr->as_string ();
1372+
str += "\n right: " + right_expr->as_string ();
1373+
str += "\n operator: " + operator_str;
1374+
}
1375+
1376+
return str;
1377+
}
1378+
13181379
std::string
13191380
AsyncBlockExpr::as_string () const
13201381
{
@@ -3818,6 +3879,12 @@ AssignmentExpr::accept_vis (HIRVisitor &vis)
38183879
vis.visit (*this);
38193880
}
38203881

3882+
void
3883+
CompoundAssignmentExpr::accept_vis (HIRVisitor &vis)
3884+
{
3885+
vis.visit (*this);
3886+
}
3887+
38213888
void
38223889
GroupedExpr::accept_vis (HIRVisitor &vis)
38233890
{

gcc/rust/hir/tree/rust-hir-visitor.h

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class HIRVisitor
4747
virtual void visit (LazyBooleanExpr &expr) = 0;
4848
virtual void visit (TypeCastExpr &expr) = 0;
4949
virtual void visit (AssignmentExpr &expr) = 0;
50+
virtual void visit (CompoundAssignmentExpr &expr) = 0;
5051
virtual void visit (GroupedExpr &expr) = 0;
5152
virtual void visit (ArrayElemsValues &elems) = 0;
5253
virtual void visit (ArrayElemsCopied &elems) = 0;

gcc/rust/lint/rust-lint-marklive-base.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class MarkLiveBase : public HIR::HIRVisitor
5353
virtual void visit (HIR::LazyBooleanExpr &) override {}
5454
virtual void visit (HIR::TypeCastExpr &) override {}
5555
virtual void visit (HIR::AssignmentExpr &) override {}
56-
56+
virtual void visit (HIR::CompoundAssignmentExpr &) override {}
5757
virtual void visit (HIR::GroupedExpr &) override {}
5858

5959
virtual void visit (HIR::ArrayElemsValues &) override {}

gcc/rust/lint/rust-lint-marklive.h

+6
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ class MarkLive : public MarkLiveBase
186186
expr.visit_rhs (*this);
187187
}
188188

189+
void visit (HIR::CompoundAssignmentExpr &expr) override
190+
{
191+
expr.visit_lhs (*this);
192+
expr.visit_rhs (*this);
193+
}
194+
189195
void visit (HIR::IfExpr &expr) override
190196
{
191197
expr.get_if_condition ()->accept_vis (*this);

gcc/rust/typecheck/rust-hir-const-fold-base.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class ConstFoldBase : public HIR::HIRVisitor
5656
virtual void visit (HIR::LazyBooleanExpr &) override {}
5757
virtual void visit (HIR::TypeCastExpr &) override {}
5858
virtual void visit (HIR::AssignmentExpr &) override {}
59-
59+
virtual void visit (HIR::CompoundAssignmentExpr &) override {}
6060
virtual void visit (HIR::GroupedExpr &) override {}
6161

6262
virtual void visit (HIR::ArrayElemsValues &) override {}

gcc/rust/typecheck/rust-hir-type-check-base.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class TypeCheckBase : public HIR::HIRVisitor
5858
virtual void visit (HIR::LazyBooleanExpr &) override {}
5959
virtual void visit (HIR::TypeCastExpr &) override {}
6060
virtual void visit (HIR::AssignmentExpr &) override {}
61-
61+
virtual void visit (HIR::CompoundAssignmentExpr &) override {}
6262
virtual void visit (HIR::GroupedExpr &) override {}
6363

6464
virtual void visit (HIR::ArrayElemsValues &) override {}

gcc/rust/typecheck/rust-hir-type-check-expr.h

+23
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,29 @@ class TypeCheckExpr : public TypeCheckBase
470470
result->clone ());
471471
}
472472

473+
void visit (HIR::CompoundAssignmentExpr &expr) override
474+
{
475+
infered = new TyTy::TupleType (expr.get_mappings ().get_hirid ());
476+
477+
auto lhs = TypeCheckExpr::Resolve (expr.get_left_expr ().get (), false);
478+
auto rhs = TypeCheckExpr::Resolve (expr.get_right_expr ().get (), false);
479+
480+
bool valid_lhs = validate_arithmetic_type (lhs, expr.get_expr_type ());
481+
bool valid_rhs = validate_arithmetic_type (rhs, expr.get_expr_type ());
482+
bool valid = valid_lhs && valid_rhs;
483+
if (!valid)
484+
{
485+
rust_error_at (expr.get_locus (),
486+
"cannot apply this operator to types %s and %s",
487+
lhs->as_string ().c_str (), rhs->as_string ().c_str ());
488+
return;
489+
}
490+
491+
auto result = lhs->unify (rhs);
492+
if (result->get_kind () == TyTy::TypeKind::ERROR)
493+
return;
494+
}
495+
473496
void visit (HIR::IdentifierExpr &expr) override
474497
{
475498
NodeId ast_node_id = expr.get_mappings ().get_nodeid ();

gcc/rust/typecheck/rust-hir-type-check-util.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class SimpleHirVisitor : public HIR::HIRVisitor
5151
virtual void visit (HIR::LazyBooleanExpr &) override {}
5252
virtual void visit (HIR::TypeCastExpr &) override {}
5353
virtual void visit (HIR::AssignmentExpr &) override {}
54-
54+
virtual void visit (HIR::CompoundAssignmentExpr &) override {}
5555
virtual void visit (HIR::GroupedExpr &) override {}
5656

5757
virtual void visit (HIR::ArrayElemsValues &) override {}

0 commit comments

Comments
 (0)