@@ -1558,15 +1558,9 @@ bool ConverterRefCount::VisitUnaryExprOrTypeTraitExpr(
15581558
15591559bool ConverterRefCount::VisitStmtExpr (clang::StmtExpr *expr) {
15601560 PushConversionKind push (*this , ConversionKind::FullRefCount);
1561- return Converter::VisitStmtExpr (expr);
1562- }
1563-
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 ());
1561+ Converter::VisitStmtExpr (expr);
1562+ SetFreshType (expr->getType ());
1563+ return false ;
15701564}
15711565
15721566void ConverterRefCount::ConvertBinaryOperator (clang::BinaryOperator *expr) {
@@ -1580,8 +1574,7 @@ void ConverterRefCount::ConvertBinaryOperator(clang::BinaryOperator *expr) {
15801574 assign && GetSafeTypeAsString (lhs_type) !=
15811575 GetSafeTypeAsString (assign->getComputationResultType ())) {
15821576 auto computation_result_type = assign->getComputationResultType ();
1583- PushBrace brace (*this );
1584- StrCat (keyword::kLet , " rhs_0" , token::kAssign );
1577+ std::optional<Buffer> buf (std::in_place, *this );
15851578 if (IsUnsignedArithOp (assign)) {
15861579 PushParen outer (*this );
15871580 {
@@ -1607,15 +1600,16 @@ void ConverterRefCount::ConvertBinaryOperator(clang::BinaryOperator *expr) {
16071600 } else {
16081601 ConvertCast (lhs_type);
16091602 }
1610- StrCat (token::kSemiColon );
1611- EmitSetOrAssign (lhs, " rhs_0" );
1603+ auto value = std::move (*buf).str ();
1604+ buf.reset ();
1605+ EmitCompoundSetOrAssign (lhs, rhs, value);
16121606 return ;
16131607 }
16141608
16151609 if (IsUnsignedArithOp (expr)) {
1616- PushBrace brace (* this , expr-> isCompoundAssignmentOp ()) ;
1610+ std::optional<Buffer> buf ;
16171611 if (expr->isCompoundAssignmentOp ()) {
1618- StrCat (keyword:: kLet , " rhs_0 " , token:: kAssign );
1612+ buf. emplace (* this );
16191613 }
16201614 {
16211615 PushParen paren (*this );
@@ -1627,8 +1621,9 @@ void ConverterRefCount::ConvertBinaryOperator(clang::BinaryOperator *expr) {
16271621 }
16281622 ConvertUnsignedArithBinaryOperator (expr, rhs);
16291623 if (expr->isCompoundAssignmentOp ()) {
1630- StrCat (token::kSemiColon );
1631- EmitSetOrAssign (lhs, " rhs_0" );
1624+ auto value = std::move (*buf).str ();
1625+ buf.reset ();
1626+ EmitCompoundSetOrAssign (lhs, rhs, value);
16321627 } else {
16331628 computed_expr_type_ = ComputedExprType::FreshValue;
16341629 }
@@ -2424,16 +2419,39 @@ void ConverterRefCount::EmitSetOrAssign(clang::Expr *lhs,
24242419 computed_expr_type_ = ComputedExprType::FreshValue;
24252420}
24262421
2422+ bool ConverterRefCount::CanBraceAssignedValue (
2423+ clang::Expr *lhs, clang::Expr *rhs, std::string_view assign_operator) {
2424+ return (assign_operator == " =" || lhs->getType ()->isArithmeticType ()) &&
2425+ !lhs->HasSideEffects (ctx_) && !rhs->HasSideEffects (ctx_);
2426+ }
2427+
2428+ void ConverterRefCount::EmitCompoundSetOrAssign (clang::Expr *lhs,
2429+ clang::Expr *rhs,
2430+ std::string_view value) {
2431+ if (CanBraceAssignedValue (lhs, rhs, " =" )) {
2432+ PushBrace brace (*this , isRValue ());
2433+ EmitSetOrAssign (lhs, std::format (" {{ {} }}" , value));
2434+ return ;
2435+ }
2436+ PushBrace brace (*this );
2437+ StrCat (keyword::kLet , " rhs_0" , token::kAssign , value, token::kSemiColon );
2438+ EmitSetOrAssign (lhs, " rhs_0" );
2439+ }
2440+
24272441void ConverterRefCount::ConvertAssignment (clang::Expr *lhs, clang::Expr *rhs,
24282442 std::string_view assign_operator) {
24292443 auto rhs_as_string = ConvertFreshRValue (rhs, lhs->getType ());
24302444
24312445 PushBrace brace (*this , isRValue ());
24322446
24332447 if (MayCauseBorrowMutError (lhs, rhs)) {
2434- StrCat (keyword::kLet , " __rhs" , token::kAssign , rhs_as_string,
2435- token::kSemiColon );
2436- rhs_as_string = " __rhs" ;
2448+ if (CanBraceAssignedValue (lhs, rhs, assign_operator)) {
2449+ rhs_as_string = std::format (" {{ {} }}" , rhs_as_string);
2450+ } else {
2451+ StrCat (keyword::kLet , " __rhs" , token::kAssign , rhs_as_string,
2452+ token::kSemiColon );
2453+ rhs_as_string = " __rhs" ;
2454+ }
24372455 }
24382456
24392457 if (assign_operator == " =" ) {
@@ -2492,7 +2510,7 @@ void ConverterRefCount::ConvertGenericBinaryOperator(
24922510
24932511 if (may_cause_borrow_mut_err) {
24942512 StrCat (std::format (
2495- " {{ let _lhs = {}; _lhs {} {} }}" ,
2513+ " ( {{ {} }} {} {{ { } }}) " ,
24962514 ConvertFreshRValue (
24972515 lhs, GetOperandImplicitConversionTarget (ctx_, expr, lhs, rhs)),
24982516 opcode,
0 commit comments