1

I was trying to write an exhaustive match statement over a (u32, usize) tuple in rust, here is a minimal example:

fn test(x: u32, y: usize) {
    match (x, y) {
        (0, 0) => todo!(),
        (0, 1..) => todo!(),
        (1.., 0) => todo!(),
        (1.., 1..) => todo!(),
    }
}

The compiler complains that this is non-exhaustive and is missing this case:

(0_u32, _) | (1_u32..=u32::MAX, _) => todo!()

Strangely this works with (u32, u32) tuples, but not a heterogeneous (u32, usize) tuple. Is this a compiler problem, or am I really missing an edge case?

abc
  • 924
  • 8
  • 19
  • 4
    This simpler [example](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=43932487da985a8d7d106a55b0e8abc6) show the same missing case but with additional details: _`usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively_, but I don't know why... – rodrigo Jul 23 '23 at 18:24
  • 1
    You could avoid the `1..` part as what else is it going to be if not `0`? Just go with `_`. – tadman Jul 23 '23 at 18:24
  • 1
    @rodrigo Your link is to the homepage of the playground. – Chayim Friedman Jul 23 '23 at 18:25
  • 1
    @tadman That is what I ended up doing, but I was curious why this would fail. – abc Jul 23 '23 at 18:28
  • Nothing wrong with asking questions, of course. – tadman Jul 23 '23 at 18:32

1 Answers1

2

This should work, and work on that is tracked on tracking issue #56354: precise pattern matching on pointer size types. The problem is that matching on usize and isize is not similar to matching on other integers, in that if you match 0..=usize::MAX you still haven't covered the whole usize range because there are different platforms. But half-open patterns should indeed be allowed.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77