Skip to content

[Suggestion] Potential Integer Overflow risk in functions5.rs exercise #2379

@foxfromworld

Description

@foxfromworld

Description

In the current version of exercises/02_functions/functions5.rs, the goal is to fix the function body by converting a statement into an expression without changing the function signature.

While the exercise successfully teaches the difference between expressions and statements, I discovered a potential Integer Overflow risk during my testing, which might be a valuable "teachable moment" for new Rustaceans.

The Observation
The current implementation uses i32 for both the input and the return type:

// TODO: Fix the function body without changing the signature.
fn square(num: i32) -> i32 {
    num * num
}

As suggested in intro1.rs, I tried to "keep trying things" even after figuring out the solution. When I changed the input in main to a boundary value, the program panicked.

Reproducible Panic Case

If we test the function with the square root of i32::MAX (approximately 46340):

fn main() {
    let answer = square(46341);
    println!("The square is {answer}");
}

Runtime Error:

thread 'main' panicked at src/main.rs:3:5:
attempt to multiply with overflow
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

A More Robust (but restricted) Approach

If we were allowed to change the signature (which this exercise specifically forbids), a safer real-world implementation would be:

fn square(num: i32) -> i64 {
    (num as i64) * (num as i64)
}

Using the maximum i32 value (2147483647) with this logic yields the correct result (4611686014132420609) without panicking.

Proposal
I understand that Rustlings exercises are designed to be "small exercises to get you used to reading and writing Rust code" and often focus on one specific concept at a time. However, considering Rust's focus on Safety, it might be beneficial to:

  1. Add a comment in functions5.rs mentioning that while this implementation works for small values like 3, it does not handle Integer Overflow.
  2. Or, simply acknowledge this as a known simplification for educational purposes.

I believe this would help learners develop the "security-first" mindset that Rust is known for.

I'm happy to provide a PR if this is something the maintainers would like to include as a comment in the exercise!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions