TL;DR loop is an expression; while true is a statement, they have different use cases and offer flexibility and expressiveness.
The main reason is that loop blocks are expressions, whereas while blocks are statements. Differentiating the both and setting distinct rules for each case allows the compiler to make optimizations without sacrificing safety.
While loop and while true loops have the same behavior (and probably similar optimizations—the condition checking at the beginning of each while true loop iteration is dropped for performance), they are still bound to their Rust implementations, and cannot be used interchangeably.
For instance, we can use loop loops like this:
let mut counter = 0; let result = loop { counter += 1; if counter == 10 { break counter * 2; // Return a value from the loop } }; println!("The result is {}", result); // The result is 20
We can see that we assign the evaluation of the loop expression to result with no problems.
On the other hand, while loops are statements, and so we cannot assign them to variables, etc.
Doing the same with a while true loop would look like this:
let mut counter = 0; let mut result = 0; while counter < 10 { counter += 1; if counter == 10 { result = counter * 2; // Assign a value inside the loop break; } }; println!("The result is {}", result); // The result is 20
If we tried to implement this simple algorithm using while true in the same way as loop would yield the following compiler error:
let mut counter = 0; let mut result = while counter < 10 { counter += 1; if counter == 10 { counter * 2; // Statement, hence () is returned break } }; println!("The result is {}", result); // `()` cannot be formatted with the default formatter
error[E0277]: `()` doesn't implement `std::fmt::Display` --> src/main.rs:10:34 | 10 | println!("The result is {}", result); // The result is 20 | ^^^^^^ `()` cannot be formatted with the default formatter | = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)