std::num::NonZero
allows user to specify a type which cannot be zero,
NonZeroI8 in std::num - Rust (rust-lang.org)
so Option<std::num::NonZero>
has the same size of std::num::NonZero
According to https://github.com/rust-lang/rust/pull/96947
rustc currently supports to specify a struct which cannot have the value of -1 (all bytes are 0xFF)
std::os::BorrowedFd
and std::os::OwnedFd
cannot be -1
However, there is no way to use them in libcore without libstd,
and there is no way to specify such struct outside of libstd, because attributes rustc_layout_scalar_valid_range_start
,
rustc_layout_scalar_valid_range_end
,
and rustc_nonnull_optimization_guaranteed
are unstable.
Since -1
is another widely used placeholder value besides zero,
can we construct custom struct, which assumed not be -1?
I know I can store NonZero
in my struct,
and +1 or -1 in methods to simulate this,
but it is a loss of performance.
I have the following proposals, from simple to hard
- Add structs
NonNegativeOneI8
,NonNegativeOneI32
,NonNegativeOneU32
, etc. tocore::num
, which specifies an integer that is known not to equal to -1 (all bytes are 0xff),
P.S.: Unsigned integer cannot be negative, but I do not find a better name than NonNegativeOne
- Add the following struct, which specify a custom value which is not allowed.
Just adding a struct for
-1
is not generic enough.
struct NonValueI8<const value: i8> {
}
Its public APIs are new_unchecked
, new
and get
, which are defined similar to NonZero
- Add the following struct, which specify a custom range of value which is not allowed.
struct NonRangeI8<const begin: i8, const end: i8> {
}
a. If begin == end
, there should be an error message
b. if begin < end
, then the compiler can assume the value not in [begin, end)
c. if begin > end
, then the compiler can assume the value not in [begin,MAX]
,
and the value not in [MIN, end)
Its public APIs are new_unchecked
, new
and get
, which are defined similar to NonZero
This effectively stabilizes rustc_layout_scalar_valid_range_start
,
rustc_layout_scalar_valid_range_end
,
and rustc_nonnull_optimization_guaranteed
,
and this is the most flexible solution.
But this solution definitely requires much more testing in the compiler.