Re: [PATCH 1/2] rust: add BitInt integer wrapping type

Alexandre Courbot
2025-11-05T14:03:31Z

On Wed Nov 5, 2025 at 4:30 AM JST, Yury Norov wrote:
> On Tue, Nov 04, 2025 at 12:13:26PM +0900, Alexandre Courbot wrote:
>> On Tue Nov 4, 2025 at 4:36 AM JST, Yury Norov wrote:
>> > On Mon, Nov 03, 2025 at 10:42:13PM +0900, Alexandre Courbot wrote:
>> >> Hi Yury,
>
> ...
>
>> let a = BitInt::<u8, 3>::new::<3>();
>> let b = BitInt::<u16, 10>::new::<123>() + a.cast::<u16>();
>>
>> let c = a.cast::<u32>() + u32::from(b);
>>
>> Note that `b` and `c` are regular `u16` and `u32`. Arithmetic operations
>> cannot guarantee that the BitInt invariant will be maintained, so the
>> result needs to be converted back if that's what one wants.
>
> What C does and what I proposed is to make BitInt a 1st class type,
> just like basic integers. What you implement is really a bounded int.
>
> Both have advantages. C-style BitInt() is a true type with all type
> guarantees. And I like it more because it is a natural extension of
> the existing integer scheme.

Yeah, it's definitely different from what we are doing here. IIUC C's
_BitInt is implemented at the compiler level, here we are just a regular
Rust project, not touching the compiler at all.

>
> Your bounded ints are actually classical integers with some limitations.

That's a very accurate way to put it. It is not an unusual thing to do
though, there are several types in the standard library (e.g. `NonZero`)
that do exactly that. Putting limitations also means we get more
guarantees, which can remove unnecessary error handling and help the
compiler produce more optimized code.

> It's not a primitive type in sense of C - it's an object. It also works
> fine. You can easily extend it to arbitrary min and max limits; you can
> expand it to floating types, and do whatever you can do with the objects.
>
> BitInt(i32, -128, 255)
> BitFloat(f32, -1, 1)
>
> That's why you think that -1i32 fits into BitInt(i32, 4), and even
> into BitInt(i8, 4), while I don't.
>
> I don't know which would work better for bitfields. Most likely both
> would work reasonably well. And if bitfield will carefully hide
> internals, I hope most users will not care much.
>
> You switched name to BitInt, but still think about it as an object,
> and that brought all the confusion in my mind. Maybe switch back to
> BoundedInt then to avoid this confusion? If you find it lengthy,
> probably LimInt or simply Lint will be better for you.

It looks like we are going to settle with just `Bounded`, to follow the
naming pattern of similar types in the Rust standard library.

>
> Looking at how good rust macros work to implement bitfields, I thought
> that they will be able to mimic native types just as well. But now it
> seems like an arbitrary-length integer types requires support on
> language side. Just like in C.

If only to be able to express arbitrary-length immediate values, yes -
although I suspect macros could also help here.

But I believe the more fundamental question is: do we need
arbitrary-length (as in, larger than primitive types) integers in the
kernel, when Rust supports up to 128-bit primitives?

>
> With that in mind, I think that bounded integers are a bit out of
> scope of basic bit operations, and probably I'm not a right person
> to maintain them neither in Rust, nor in C.
>
> Please keep me in CC for next versions.

Will do.

Also jumping on Danilo's suggestion I will probably propose to add a
MAINTAINERS entry for this in the next revision (up to the Rust core
team to take it or not :)). Let me know if you want to be a reviewer,
that would be a good way to keep up with what happens here.