Impl Range and RangeInclusive for NonZeroU<*>

note: I am only speaking about unsigned non zero integers

Problem

Currently, when looping over a range of NonZeroU<> integers, you have to use the awkward NonZeroU<*>::new or NonZeroU<*>::new_unchecked functions, even though Ranges of NonZeroU<> values are trivial:

A range of unsigned integers is either empty or it contains zero in exactly one case: when it starts from zero, thus any NonZeroU<*> Range, inclusive or otherwise, will never panic/be undefined behavior.

Am I missing something or has this not yet been worked on?

Use case

A bit contrived, but I am currently working on a Sudoku solver, it uses 0 to represent an empty cell, thus Option<NonZeroU<*>> is a natural way to represent a cell, but it is very awkward to do a very simple backtracking solver as when you try to loop over the possible values you have to use NonZeroU<*>::new or NonZeroU<*>::new_unchecked.

1 Like

I assume what you're after is Range<NonZeroU32>: Iterator etc. to allow for x in (const { NonZeroU32::new(1).unwrap() }..const { NonZeroU32::new(5).unwrap() }) { ... }?

This is controlled via a blanket impl impl Iterator for Range<impl Step>, so what would be required is impl Step for NonZeroU32 etc. That trait seems trivial to implement for the nonzero types, I found one previous request to add it, this probably just requires someone to create a draft impl to make sure it's possible and file an ACP to get the process started.

2 Likes

Actually, I forgot to search the libs-team repo too, there is an open ACP already

2 Likes

Hmm, an interesting consequence of this is that we could have RangeInclusive<NonZeroUsize>: ExactSizeIterator even though RangeInclusive<usize>: !ExactSizeIterator.

3 Likes

Thanks for the replies, I've turned on notifications for those issues and if I have time I will look over the process to maybe submitting a pull request about it, it seems fairly straightforward to implement.

If you have the time to elaborate, how did you find these issues? I totally missed the libs-team repo, but I thought I did a through search of the rust issues...

Looks like the searches I used were:

(Most of the time when looking for something like this I remove the is:issue is:open default to see if there were any relevant PRs or closed issues, then it's just a matter of being able to quickly skim the far too many results that gives).