Regarding NonZeroXX

Sometimes in generic code I'd like to write:

let m: NonZero<T> = NonZero::new(50_515_093).unwrap();

Where T is i32, instead of:

let m = NonZeroI32::new(50_515_093).unwrap();

Do you know why NonZeroXX has such hardcoded design?

Presumably this is because traits are open (i.e. must allow for new implementations added in the future), and this was not desired in this case. But I do not know for sure.

1 Like

In a sense, the integer types in Rust are all sort of hard coded, as in many methods are duplicated on all integer types as opposed to live in traits. The num crate has a lot of such traits; for example, num::PrimInt encapsulates common operations on primitive integers. It might be possible to build a version of NonZero based on these traits.

Because we don't have traits for Integer to bound T for integer types only.

2 Likes

There is also maths-traits::[...]::Zero.

1 Like

Actually, in the start we had NonZero<T>, which was replaced by concrete NonZero* types. Read this RFC for more info: https://github.com/rust-lang/rfcs/pull/2307.

1 Like