@@ -1561,14 +1561,6 @@ bool ConverterRefCount::VisitStmtExpr(clang::StmtExpr *expr) {
15611561 return Converter::VisitStmtExpr (expr);
15621562}
15631563
1564- void ConverterRefCount::EmitStmtExprTail (clang::Expr *tail) {
1565- StrCat (" let __result = " );
1566- Convert (tail);
1567- StrCat (token::kSemiColon );
1568- StrCat (" __result" );
1569- SetFreshType (tail->getType ());
1570- }
1571-
15721564void ConverterRefCount::ConvertBinaryOperator (clang::BinaryOperator *expr) {
15731565 auto *lhs = expr->getLHS ();
15741566 auto *rhs = expr->getRHS ();
@@ -1580,8 +1572,7 @@ void ConverterRefCount::ConvertBinaryOperator(clang::BinaryOperator *expr) {
15801572 assign && GetSafeTypeAsString (lhs_type) !=
15811573 GetSafeTypeAsString (assign->getComputationResultType ())) {
15821574 auto computation_result_type = assign->getComputationResultType ();
1583- PushBrace brace (*this );
1584- StrCat (keyword::kLet , " rhs_0" , token::kAssign );
1575+ std::optional<Buffer> buf (std::in_place, *this );
15851576 if (IsUnsignedArithOp (assign)) {
15861577 PushParen outer (*this );
15871578 {
@@ -1607,15 +1598,16 @@ void ConverterRefCount::ConvertBinaryOperator(clang::BinaryOperator *expr) {
16071598 } else {
16081599 ConvertCast (lhs_type);
16091600 }
1610- StrCat (token::kSemiColon );
1611- EmitSetOrAssign (lhs, " rhs_0" );
1601+ auto value = std::move (*buf).str ();
1602+ buf.reset ();
1603+ EmitCompoundSetOrAssign (lhs, rhs, value);
16121604 return ;
16131605 }
16141606
16151607 if (IsUnsignedArithOp (expr)) {
1616- PushBrace brace (* this , expr-> isCompoundAssignmentOp ()) ;
1608+ std::optional<Buffer> buf ;
16171609 if (expr->isCompoundAssignmentOp ()) {
1618- StrCat (keyword:: kLet , " rhs_0 " , token:: kAssign );
1610+ buf. emplace (* this );
16191611 }
16201612 {
16211613 PushParen paren (*this );
@@ -1627,8 +1619,9 @@ void ConverterRefCount::ConvertBinaryOperator(clang::BinaryOperator *expr) {
16271619 }
16281620 ConvertUnsignedArithBinaryOperator (expr, rhs);
16291621 if (expr->isCompoundAssignmentOp ()) {
1630- StrCat (token::kSemiColon );
1631- EmitSetOrAssign (lhs, " rhs_0" );
1622+ auto value = std::move (*buf).str ();
1623+ buf.reset ();
1624+ EmitCompoundSetOrAssign (lhs, rhs, value);
16321625 } else {
16331626 computed_expr_type_ = ComputedExprType::FreshValue;
16341627 }
@@ -2424,16 +2417,39 @@ void ConverterRefCount::EmitSetOrAssign(clang::Expr *lhs,
24242417 computed_expr_type_ = ComputedExprType::FreshValue;
24252418}
24262419
2420+ bool ConverterRefCount::CanBraceAssignedValue (
2421+ clang::Expr *lhs, clang::Expr *rhs, std::string_view assign_operator) {
2422+ return (assign_operator == " =" || lhs->getType ()->isArithmeticType ()) &&
2423+ !lhs->HasSideEffects (ctx_) && !rhs->HasSideEffects (ctx_);
2424+ }
2425+
2426+ void ConverterRefCount::EmitCompoundSetOrAssign (clang::Expr *lhs,
2427+ clang::Expr *rhs,
2428+ std::string_view value) {
2429+ if (CanBraceAssignedValue (lhs, rhs, " =" )) {
2430+ PushBrace brace (*this , isRValue ());
2431+ EmitSetOrAssign (lhs, std::format (" {{ {} }}" , value));
2432+ return ;
2433+ }
2434+ PushBrace brace (*this );
2435+ StrCat (keyword::kLet , " rhs_0" , token::kAssign , value, token::kSemiColon );
2436+ EmitSetOrAssign (lhs, " rhs_0" );
2437+ }
2438+
24272439void ConverterRefCount::ConvertAssignment (clang::Expr *lhs, clang::Expr *rhs,
24282440 std::string_view assign_operator) {
24292441 auto rhs_as_string = ConvertFreshRValue (rhs, lhs->getType ());
24302442
24312443 PushBrace brace (*this , isRValue ());
24322444
24332445 if (MayCauseBorrowMutError (lhs, rhs)) {
2434- StrCat (keyword::kLet , " __rhs" , token::kAssign , rhs_as_string,
2435- token::kSemiColon );
2436- rhs_as_string = " __rhs" ;
2446+ if (CanBraceAssignedValue (lhs, rhs, assign_operator)) {
2447+ rhs_as_string = std::format (" {{ {} }}" , rhs_as_string);
2448+ } else {
2449+ StrCat (keyword::kLet , " __rhs" , token::kAssign , rhs_as_string,
2450+ token::kSemiColon );
2451+ rhs_as_string = " __rhs" ;
2452+ }
24372453 }
24382454
24392455 if (assign_operator == " =" ) {
@@ -2492,7 +2508,7 @@ void ConverterRefCount::ConvertGenericBinaryOperator(
24922508
24932509 if (may_cause_borrow_mut_err) {
24942510 StrCat (std::format (
2495- " {{ let _lhs = {}; _lhs {} {} }}" ,
2511+ " ( {{ {} }} {} {{ { } }}) " ,
24962512 ConvertFreshRValue (
24972513 lhs, GetOperandImplicitConversionTarget (ctx_, expr, lhs, rhs)),
24982514 opcode,
0 commit comments