6.3Compound assignment: the missing ++

Last updated June 12, 2026

Back in lesson 1.10, a warning box used count += 1 and attached an IOU reading "compound assignment, lesson 6.3". Here we are.

The most common thing programs do to a variable is fold something into it: add to a total, double a score, knock a balance down. Spelled with what you know so far, that's the variable's name written twice:

fn main() {
    let mut total = 100;
    total = total + 25;
    println!("{total}");
}
125

It works, but the repetition is noise, and for once the shortcut is older than the long way. A compound assignment operator applies an arithmetic operator and an assignment in one stroke:

OperatorThis......means this
+=x += yx = x + y
-=x -= yx = x - y
*=x *= yx = x * y
/=x /= yx = x / y
%=x %= yx = x % y

(The bitwise operators in lesson 6.6 have compound forms too: &=, |=, ^=, <<=, >>=. Same idea.)

fn main() {
    let mut total = 100;
    total += 25;
    total -= 5;
    total *= 2;
    println!("{total}");
}
240

Since these assign, the variable must be mut, and all of lesson 1.4's rules apply. And like plain assignment (lesson 1.10), a compound assignment is an expression whose value is the unit type (), not the new value of the variable. You can't chain it, can't print it, can't smuggle it into a condition: the if x = 5 mistake that lesson 4.7 showed you stays a type error in compound form. Rust assignments do their job and say nothing.

Best practice

When the left side would repeat, use the compound form: total += tax, not total = total + tax. It's shorter, it can't misspell the second mention of the name, and every reader's eye is trained on it.

Where's ++?

If you've seen C, C++, Java, or JavaScript, you know those languages bless the +1 case with dedicated operators: ++ to increment, -- to decrement. Rust does not have them. This was a decision, not an oversight, and it's worth a minute, because the reasoning is a small window into how Rust weighs convenience against trouble.

C's ++ isn't one operator; it's four. ++x and x++ both add 1, but they're expressions with different values: ++x evaluates to the value after the increment, x++ to a copy of the value before it. Every C programmer has burned an afternoon on that distinction. Worse, because each one is an expression carrying a side effect, it invites being nested inside larger expressions, where it collides with the operand-evaluation-order problem from lesson 6.1: a C call like add(x, ++x) can produce different results on different compilers. Two characters of convenience, three categories of bug.

Rust's position: incrementing is a statement, not a value. Write x += 1; and move on. The price is two keystrokes; the refund is that an entire family of interview questions stops compiling:

fn main() {
    let mut x = 5;
    x++;
    println!("{x}");
}
error: Rust has no postfix increment operator
 --> src/main.rs:3:6
  |
3 |     x++;
  |      ^^ not a valid postfix operator
  |
help: use `+= 1` instead
  |
3 -     x++;
3 +     x += 1;
  |

The compiler knows exactly what you reached for and hands you the house version.

Warning

The decrement spelling is sneakier. --x is not an error: it parses as two unary minuses, "negate the negation of x", a perfectly legal expression that equals x and changes nothing. The compiler does notice the suspicious shape and warns (use of a double negation, with the note "use -= 1 if you meant to decrement the value"), but a warning won't stop the build: code migrated from C can still run with a --x that quietly stopped decrementing. If a countdown won't count down, check the warnings you skimmed past (lesson 0.11's sermon, proven right again).

Quiz time

Question #1

What does this print? Trace it line by line.

fn main() {
    let mut n = 7;
    n *= 3;
    n -= 1;
    n %= 6;
    n += 10;
    println!("{n}");
}
Show solution
12

7 * 3 is 21; minus 1 is 20; 20 % 6 is 2 (three sixes fit, remainder 2); plus 10 is 12.

Question #2

Predict the compiler's reaction:

fn main() {
    let mut lives = 3;
    ++lives;
    println!("{lives}");
}
Show solution

error: Rust has no prefix increment operator, with the same help (use += 1 instead) the postfix version gets. (Prefix gets caught because a leading ++ can't be parsed as anything legal; contrast the --x trap from this lesson's warning box, which compiles as a double negation and only draws a warning.)

Question #3

This fragment arrived from C. Rewrite the marked lines as idiomatic Rust, keeping the behavior.

score = score + level * 10;
bonus = bonus - 1;
combo = combo * 2;
Show solution
score += level * 10;
bonus -= 1;
combo *= 2;

Note the first one: * outranks +='s implied addition, so score += level * 10 adds the product, exactly like the original. Compound assignment has the lowest precedence of all, per lesson 6.1's table: everything on the right settles first.

So far the operators in this chapter have computed numbers. The next two lessons cover the operators that compute answers: true or false, including (at last) the float-comparison tool lesson 4.5 promised you.