# Empty range pattern check is superfluous and inconvenient

**URL:** <https://internals.rust-lang.org/t/empty-range-pattern-check-is-superfluous-and-inconvenient/22846>\
**Category:** language design\
**Created:** [May 2, 2025, 6:34pm UTC](https://internals.rust-lang.org/t/empty-range-pattern-check-is-superfluous-and-inconvenient/22846 "2025-05-02T18:34:14Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![kotauskas](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kotauskas/32/7217_2.png) [@kotauskas](https://internals.rust-lang.org/u/kotauskas)\
**Post date:** [May 2, 2025, 6:34pm UTC](https://internals.rust-lang.org/t/empty-range-pattern-check-is-superfluous-and-inconvenient/22846/1 "2025-05-02T18:34:14Z")

</div>

The following currently fails to compile with the highly infuriating [E0579](https://doc.rust-lang.org/error_codes/E0579.html):

```rust
match 1_u8 {
    0..0 => "intentionally dead arm",
    _ => "not so dead",
}

```

The use case is as follows:

```rust
macro_rules! match_range {
    ($e:expr, $ty:ty, {$($tt:tt)*}) => {
        match $e.get() {
            0..<$ty as $crate::int::RangeNewtype>::LOW
            | <$ty as $crate::int::RangeNewtype>::HIGH.. => unsafe { $crate::int::unreachable_unchecked() },
            $($tt)*
        }
    };
}

```

Here, `$ty` is a newtype wrapper around some integer type with a restricted range of possible values as generated by another macro that outputs an implementation of the (unsafe) `RangeNewtype` trait in addition to the type and its other methods. `match_range!`, then, is there to be a convenient, safe and zero-cost way to satisfy the exhaustiveness checker when matching the possible values of such a type.

The role of this problem in the greater range-restricting integer newtype story is marginal, as a properly compiler-visible and nicheopt-friendly way of doing this could just integrate with the exhaustiveness checker to remove the need for this macro entirely, but in the meantime, what could just as easily be a run-of-the-mill compiler warning is an unnecessary and obstructive hard error, as illustrated by the lack of convincing reasoning in favor of the existence of the error in the documentation of E0579.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [May 2, 2025, 7:15pm UTC](https://internals.rust-lang.org/t/empty-range-pattern-check-is-superfluous-and-inconvenient/22846/2 "2025-05-02T19:15:34Z")

</div>

You could give it some pre-processing

```rust
trait RangeNewtypeMatchBounds: RangeNewtype {
    const _MATCH_LOWER_BOUND: u8 = if Self::LOW > 0 { 0 } else { Self::HIGH };
    const _MATCH_UPPER_BOUND: u8 = if Self::LOW > 0 {
        Self::LOW - 1
    } else {
        Self::HIGH
    };
}
impl<T: RangeNewtype + ?Sized> RangeNewtypeMatchBounds for T {}

```

and then use

```rust
    <$ty as $crate::RangeNewtypeMatchBounds>::_MATCH_LOWER_BOUND
            ..=<$ty as $crate::RangeNewtypeMatchBounds>::_MATCH_UPPER_BOUND
    | <$ty as $crate::RangeNewtype>::HIGH.. => unsafe { $crate::unreachable_unchecked() },
    $($tt)*

```

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jrose/32/9591_2.png) [@jrose](https://internals.rust-lang.org/u/jrose)\
**Post date:** [May 2, 2025, 9:12pm UTC](https://internals.rust-lang.org/t/empty-range-pattern-check-is-superfluous-and-inconvenient/22846/3 "2025-05-02T21:12:13Z")

</div>

I’m with @kotauskas on this one, `5..5` should be an error-by-default lint rather than a hard error, especially since that’s a valid range _value_ you can form. (`5..4` can continue being a hard error.)

---

<div class="post-metadata">

**Author:** ![mathstuf](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@mathstuf](https://internals.rust-lang.org/u/mathstuf)\
**Post date:** [May 5, 2025, 7:41pm UTC](https://internals.rust-lang.org/t/empty-range-pattern-check-is-superfluous-and-inconvenient/22846/4 "2025-05-05T19:41:43Z")

</div>

What is `a..b` where `a == 5` and `b == 4` (at runtime)? The docs just say it is "empty" if `a >= b`, not a runtime error. So why compiler-error for something that has well-defined runtime behavior?

---

<div class="post-metadata">

**Author:** ![jrose](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jrose/32/9591_2.png) [@jrose](https://internals.rust-lang.org/u/jrose)\
**Post date:** [May 5, 2025, 8:07pm UTC](https://internals.rust-lang.org/t/empty-range-pattern-check-is-superfluous-and-inconvenient/22846/5 "2025-05-05T20:07:14Z")

</div>

We’re talking about patterns, not expressions, and range patterns match integers, not other ranges. So while `5..5` and `5..4` both won’t match any actual values, the latter is _much more likely_ to be a mistake, and so allowing the former while still diagnosing the latter is desirable. But sure, I guess it could be a _second_ error-by-default lint.
