Just suggesting this off the top of my head. Currently building NonZero
integers requires either unsafe
construction or a runtime-checked (non const
!) construction.
Both options are very disappointing when creating these NonZero
values out of integer literals: either the input literal is 0, and compilation should fail, or it is not, and the unsafe conversion is valid.
So I was think of some proc-macro with a behavior along the following lines:
macro_rules! nonzero_u8 {
(0) => (compile_error!("0 is not nonzero!"));
(1) => (unsafe {
::std::num::NonZeroU8::new_unchecked(1)
});
(2) => (unsafe {
::std::num::NonZeroU8::new_unchecked(2)
});
(3) => (unsafe {
::std::num::NonZeroU8::new_unchecked(3)
});
// etc.
(255) => (unsafe {
::std::num::NonZeroU8::new_unchecked(255)
});
($other:tt) => (compile_error!("nonzero_u8! requires an integer literal in base 10"));
}
I have tested it while having the macro as an external crate, and when used with 0
, we get the following error:
error: 0 is not nonzero!
--> src/main.rs:6:24
|
6 | let x: NonZeroU8 = nonzero_u8!(0);
| ^^^^^^^^^^^^^^
|
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
With a proc_macro, obviously, we could get it to work even for NonZeroU64
, and for any kind of literal syntax (e.g., 1_024_u32
).
Now, the obvious answer is that this can be done in an external crate, and thus std
is not required.
- I have actually done that for
&'static CStr
literals, which suffer from exactly the same problem.
I think, however, that since it saves runtime cost or unsafe
usage, this can definitely go to std
(or even core
!)
Obviously, that's just my opinion, so I would like to have your thoughts on this:
- I think avoiding
unsafe
makes itstd
-worthy - This should just be an external crate
0 voters