I've recently noticed, that overflow checks are disabled in release mode even in const evaluation. For example:
pub const fn add(a: u8, b: u8) -> u8 {
a + b
}
pub const FOO: u8 = add(200, 200);
pub const BAR: u8 = const { add(200, 200) };
fn main() {
println!("{FOO}");
println!("{BAR}");
}
This code will fail to compile in debug build with following errors:
compiler's output
Compiling playground v0.0.1 (/playground)
error[E0080]: evaluation of constant value failed
--> src/main.rs:2:5
|
2 | a + b
| ^^^^^ attempt to compute `200_u8 + 200_u8`, which would overflow
|
note: inside `add`
--> src/main.rs:2:5
|
2 | a + b
| ^^^^^
note: inside `FOO`
--> src/main.rs:5:21
|
5 | pub const FOO: u8 = add(200, 200);
| ^^^^^^^^^^^^^
error[E0080]: evaluation of `BAR::{constant#0}` failed
--> src/main.rs:2:5
|
2 | a + b
| ^^^^^ attempt to compute `200_u8 + 200_u8`, which would overflow
|
note: inside `add`
--> src/main.rs:2:5
|
2 | a + b
| ^^^^^
note: inside `BAR::{constant#0}`
--> src/main.rs:6:29
|
6 | pub const BAR: u8 = const { add(200, 200) };
| ^^^^^^^^^^^^^
note: erroneous constant encountered
--> src/main.rs:6:21
|
6 | pub const BAR: u8 = const { add(200, 200) };
| ^^^^^^^^^^^^^^^^^^^^^^^
note: erroneous constant encountered
--> src/main.rs:10:16
|
10 | println!("{BAR}");
| ^^^
note: erroneous constant encountered
--> src/main.rs:9:16
|
9 | println!("{FOO}");
| ^^^
note: erroneous constant encountered
--> src/main.rs:9:15
|
9 | println!("{FOO}");
| ^^^^^
|
= note: this note 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)
note: erroneous constant encountered
--> src/main.rs:10:15
|
10 | println!("{BAR}");
| ^^^^^
|
= note: this note 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)
For more information about this error, try `rustc --explain E0080`.
error: could not compile `playground` (bin "playground") due to 2 previous errors
But in release mode it builds and runs:
144
144
This worries me somewhat. I cannot say that this breaks any rules, because technically overflows are well defined in Rust, but this just feels wrong. To me overflow => bug
. I understand compromise Rust made and I quite like it. But I don't understand why constant evaluation doesn't have stricter rules (it already does for example stricter unsafe
code rules).
Is there some option to enable overflow checks in const eval regardless of release mode? Has this been discussed before? I couldn't find any answers myself. And if it really is impossible to to this now, do you think it should stay this way? It probably is possible for the compiler to do this, right?