Just popping in to share a somewhat surprising behavior I encountered.
The anonymous const assertion in the ranged
macro, produces a compile error by wrongly interpreting $min
and $max
literals as i32
s at build time.
I find it surprising that the compiler can't infer the correct type in this very unambiguous context (value
, min
and max
fields of the Error
type are i64
s, value
's type is explicitly annotated etc.).
And it does the same if the whole macro is invoked in a const context.
Also, the error message is confusing: assertion failed: 0 <= 2_147_483_648
(which is obviously wrong). A more insightful message would be to something like literal '2_147_483_648' does not fit into the type 'i32'
.
Do you think this is worth reporting? In which case where and how should I report it?
#[derive(Debug)]
pub struct Error {
value: i64,
min: i64,
max: i64
}
macro_rules! ranged {
($value:ident in $min:literal..=$max:literal) => {{
// wrong interpretation of $min and $max as i32 at build time
const _: () = assert!($min <= $max);
// workaround
const _: () = assert!($min as i64 <= $max as i64);
// correct interpretation of $min and $max as i64 at run time
if $value < $min || $max < $value {
return Err(Error {
value: $value,
min: $min,
max: $max,
});
}
}}
}
fn main() -> Result<(), Error> {
let value: i64 = 42;
// works
ranged!(value in 0..=2_147_483_647); // i32::MAX
ranged!(value in 0i64..=2_147_483_648); // i32::MAX + 1
ranged!(value in 0..=2_147_483_648i64);
// compile error
ranged!(value in 0..=2_147_483_648);
Ok(())
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0080]: evaluation of constant value failed
--> src/main.rs:13:23
|
13 | const _: () = assert!($min <= $max);
| ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: 0 <= 2_147_483_648', src/main.rs:39:5
...
39 | ranged!(value in 0..=2_147_483_648);
| ----------------------------------- in this macro invocation
|
= note: this error originates in the macro `assert` which comes from the expansion of the macro `ranged` (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 1 previous error