Elegant way to prevent unused assignment?

Viewed 384

Context

Sometimes I find strict typing warnings more distracting than useful while still putting some idea into code, and before having reviewed it for sanity.

I'm looking for a quick programmatic way to prevent "unused declaration" warning, in order to boost my workflow.

Example

I'll try to illustrate what I mean by an example.

// use rand::Rng;

fn breaking_out_of_nested_loops_using_labels() {
    let mut innermost_loop_reached: bool = false;

    'outermost_loop: loop {
        loop {
            // if rand::thread_rng().gen::<u8>() >= u8::MAX / 2 {
            //    break;
            // }

            loop {
                innermost_loop_reached = true;
                break 'outermost_loop;
            }
        }
    }

    println!(
        "Inner loop was {}reached",
        if innermost_loop_reached { "" } else { "not " }
    )
}

The code results with the following warning:

compiler warning, indicating an unused assignment

Obviously the compiler is correct.

Question

I'm curious if there is a quick way to "trick" or ignore unused assignment warnings during typing some initial code, when all you want to know is if the code still compiles.

How do experienced rust programmers go about this? or do you just learn to ignore the warnings until you're ready to process them?

Please note

The commented out code is what I used to prevent the warning from popping up, while still trying the code. Obviously importing a crate and using a random condition is a lot of work, so it's not ideal.

At that point I might as well put the #[allow(unused_assignments)]-allow-rule above my function. But that's what I'm trying to prevent having to do, because;

  • I might forget to remove it.
  • It would already interrupt my workflow if I have to copy warnings from the compiler output.
3 Answers

You can try naming the variable _innermost_loop_reached instead.

Adding an underscore in the beginning of the name of a variable prevents the compiler from showing the unused_assignments warning.

You can control lint levels via rustc flags - so for example -A unused_assignments would banish the unused assignments warning.

You can configure Cargo so that it applys specific flags when it calls rustc using a config.toml file, which you can place in the project, or your in ~/.cargo/config.toml, or a number of other places - refer to the cargo documentation.

You place the desired rust flags inside the [build] section like this:

[build]
rustflags = ["-A", "unused_assignments"]

Of course you still need to remember to remove this when you are finished the initial experimental coding phase, but at least it is not sprinkled throughout your code.

Unfortunately it is not possible yet to set the rustflags per profile - it might be great to be able to dampen down the warnings for debug but keep them all for release. There is a feature request open for this so maybe it will be possible in the future.

You can also control the rust arguments with the RUSTFLAGS environment variable. I generally find this less useful for environments like IDEs though, which might make it hard to control the environment variables under which cargo is running.

One solution is to avoid the problem altogether by making using of the fact that loop can be an expression, and assign that expresion to innermost_loop_reached:

fn breaking_out_of_nested_loops_using_labels() {
    // Directly assign to `innermost_loop_reached`
    let innermost_loop_reached: bool = 'outermost_loop: loop {
        loop {
            if rand::thread_rng().gen::<u8>() >= u8::MAX / 2 {
                break;
            }

            loop {
                // break directly to the top-loop, "returning" `true`
                break 'outermost_loop true;
            }
        }
        // "return" `false`
        break false;
    };

    println!(
        "Inner loop was {}reached",
        if innermost_loop_reached { "" } else { "not " }
    )
}

This has the added benefit that all exits from the loop (via break) must be of type bool because innermost_loop_reached is a bool. That is, you avoid most cases where innermost_loop_reached should get a value in the loops but doesn't, wrongfully leaving the default false from your example in place.

Related