While a == 10 incorrect?

Why does the rustc compiler successfully compile code that contains a logically incorrect condition?

fn main() {
let mut a = 1;
while a == 10 {

    println!("{}", a);
    a += 1;

}

}

The compiled binary doesn’t produce any output, but intuitively, the compiler should detect that the loop condition (a == 10) will never be true.

Trying to detect cases like this is a tarpit of more and more complex analyses, and can never be complete, so the compiler mostly does not try. There are some lints for common mistakes, but this is not a common mistake.

1 Like

What does that even mean? You wrote some condition that's always producing false, compiler successfully detected it and eliminated dead code… what else do you expect to happen?

Sometimes compiler detects nonsense conditions that are happening often. but what you wrote doesn't happen often…

There is nothing incorrect with the code as it follows the rules of the language.
With release it optimises out anything it finds unreachable.
Reporting such could probably be added to clippy

2 Likes

I don't see any logically incorrect condition there. You get what you order.

The problem is that Rust doesn't have until loops.

Why is that a problem? Referring to the Bash until loop, it is equivalent to

while !CONDITION {
//...
}

Can't it report that though?

So the program is valid Rust, but it contains dead code.

Maybe that's what OP refers to, and maybe what kpreid replied to, I am unsure.

But where should it stop?

Like almost every program in Rust. Even something like let x = 2 + 2 includes dead code, that's eliminated by compiler (panic that may happen in addition of 2 + 2 and that's provadly not happening).

Do you want to get 1000 lines of warning from every 100 lines of valid Rust code? Who would use such compiler and what for?

We would need clarifications form OP to know. Right now it sounds like “rust compiler thinks that program is good and it's obviously bad, why compiler couldn't say that”… well, we have about trillion dollars spent on that problem[1] and we can see how “reliably” that works[2].

Rust developers, kinda, don't like technologies that produce awful, unpredictable, results, thus they picked the definition of Rust which may not please someone (you may never please everyone), but which is, at least, can be reliably compared to its definition… that program complies thus it works.


  1. In the form of LLM research. ↩︎

  2. Hint: not reliable at all. ↩︎

Not a problem at all, however how do you implement:

do {
printf("hello, boy/n");
} until (1);

?

The compiler is type-based. If you want the compiler to reliably detect things, encode them in types.

If you're using value-based logic, this is what unit tests are for.

1 Like

so you mean that the syntactic sugar for what can be described as a do { ... } while ... loop is missing?

I wouldn't say - missing. It is intentionally not included. My most frequent logical mistake is using the ending condition wrong. So Rust eliminated the problem for me when I use Rust.

I'm not missing this, but if you do, you can trivially write a macro that will add this kind of loop.

This is simply correct code. Why should there be any error? a is 1, the while guard is a == 10, so the code does not enter the loop because of the apparent reason, and the program terminates without printing the output, but how can the compiler know this was not the original intention of the human? Humans are strange at times. Maybe this is just poorly written code to do nothing that could be optimized to fn main() {} . Humans, at times, write a little more code than is minimally needed.

1 Like

For me it is sometimes the other way round -- clippy is worried about code that is fine for me like

  if false && SELECT_EXTEND {

or

  if false && is_queen_or_king(el.sf) && g.move_chain[cup as usize] == el.si {

I am using this "if false &&" often to temporary or even permanently disable code segments. This way I can keep the code content, formatting, and highlighting, and even ensure that it compiles, but prevent that it is actually executed.

would make sense to have an unreacheable code warning but otherwise it's correct

Not aesthetically pleasing, but can you use cfg!(any()) instead of false and all() for the true case? That should silence clippy without actually silencing clippy.

1 Like

It's absolutely fabulous recommendation. When I start working I needed to write code in assembler of IBM360/370. It was a nightmare until I found the structured assembler macro library. I had normal if/then/else, and for loop after, and my productivity was increased in x10 times.

It looks like we think equal, I also like this approach and I use if true || in addition.