A code line to multiply such as (x * x) with a semicolon in a function definition throws compilation error

A semicolon placed at line 9 throws a compilation error. But why, what is different at line 9 (x * x); ?
And program builds and runs fine when semicolon is removed.

  1 /* sample program for function  */
  3 fn main() {
  4     let x = 2;
  5     println!("{}",  get_square_value(x));
  6 }
  8 fn get_square_value(x: i32) -> i32 {
  9     (x * x); 
 10 }

Build error:

$ rustc -o f01 function-01.rs 
error[E0308]: mismatched types
  --> function-01.rs:8:36
8  |   fn get_square_value(x: i32) -> i32 {
   |  ____________________________________^
9  | |     (x * x);
10 | | }
   | |_^ expected (), found i32
   = note: expected type `()`
              found type `i32`
help: consider removing this semicolon:                              << ? 
  --> function-01.rs:9:12
9  |     (x * x);
   |            ^

error: aborting due to previous error

The ';' makes this a statement instead of an expression.

You can write:

return (x*x);


(x * x)

An expression at the end of any block is the return type of that block.

You should really read "The Book" to get your head around this as this is one of the very basic pieces of Rust. And it gets involved from here out.


@daveb68 thanks for the clarification.
Actually yeah just started reading. And I was carried away, understanding that the last statement will be the return value even without a explicit return keyword.
So I tried (x * x); as I thought the 'return' is implied because its the last statement of the function.

I am almost as new as you.

I was burnt the other day with the actix-web library having an automatic conversion from the unit type '()' to an expected return type of a function. Because of this, the ; changed what should have been an expression to a statement, the last expression (no expression) was the unit type, and the compiler converted it to the return type automatically. i.e. a runtime behavioral error the compiler could not catch.

Of course the community is very responsive and I believe the authors of the actix-web crate have removed the implicit conversion from the unit type moving forward to avoid this type of issue.

@daveb68 oh that was a interesting catch. Glad you narrowed it down. How do you debug generally? Is there a gdb option or do you do that from the IDE..
I mean to step through code.

I am still getting my head around the language and best practices. But I have been able to successfully use the debugger in Visual Studio Code to set breakpoints and walk through the very small programs I have worked on to date.