DEV Community

Cover image for One Semicolon Changed My Rust Code: Expressions vs Statements
Harsh Mangalam
Harsh Mangalam

Posted on AI-assisted

One Semicolon Changed My Rust Code: Expressions vs Statements

I added one semicolon to my Rust code.

It stopped compiling.

This worked:

fn add(a: i32, b: i32) -> i32 {
    a + b
}
Enter fullscreen mode Exit fullscreen mode

Then I wrote this:

fn add(a: i32, b: i32) -> i32 {
    a + b;
}
Enter fullscreen mode Exit fullscreen mode

Same calculation.

Same numbers.

Just one ;.

And Rust basically said: Nope.

So what changed?

The missing piece: expressions

In Rust, an expression produces a value.

For example:

5 + 10
Enter fullscreen mode Exit fullscreen mode

produces:

15
Enter fullscreen mode Exit fullscreen mode

So when Rust sees:

fn add(a: i32, b: i32) -> i32 {
    a + b
}
Enter fullscreen mode Exit fullscreen mode

the last line is an expression.

It produces an i32.

And because it's the final expression in the function, that value becomes the function's result.

No return needed.

So what did ; do?

Adding the semicolon changes how that expression is used:

a + b;
Enter fullscreen mode Exit fullscreen mode

Now the a + b value isn't being used as the block's final value.

But the function promised:

-> i32
Enter fullscreen mode Exit fullscreen mode

So Rust asks:

"You promised me an i32. Where is it?"

And that's why this fails.

The fix is surprisingly simple:

fn add(a: i32, b: i32) -> i32 {
    a + b
}
Enter fullscreen mode Exit fullscreen mode

Remove the semicolon.

And then Rust gets interesting

Here's something I didn't expect:

let result = {
    let price = 100;
    let discount = 20;

    price - discount
};

println!("{}", result);
Enter fullscreen mode Exit fullscreen mode

The entire block produces a value.

So this:

{
    let price = 100;
    let discount = 20;

    price - discount
}
Enter fullscreen mode Exit fullscreen mode

evaluates to:

80
Enter fullscreen mode Exit fullscreen mode

Which means:

block
  ↓
price - discount
  ↓
80
  ↓
result
Enter fullscreen mode Exit fullscreen mode

That's the part that made the earlier function finally click for me.

Rust isn't just about statements that execute one after another.

Expressions can produce values, and blocks can produce expressions.

And suddenly things like if, match, and function returns start making a lot more sense.

The takeaway

When you see a Rust expression without a semicolon, don't automatically think:

"Someone forgot ;."

Sometimes that missing semicolon is the whole point.

🦀 In Rust, one tiny ; can change whether your code produces a value or simply performs an action.

Top comments (0)