Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stabilise exhaustive integer pattern matching #2591

Merged
merged 6 commits into from
Nov 30, 2018
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions text/0000-exhaustive-integer-pattern-matching.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
- Feature Name: `exhaustive_integer_patterns`
- Start Date: 10/11/2018
- RFC PR:
- Rust Issue: [#50907](https://github.com/rust-lang/rust/issues/50907)

# Summary
[summary]: #summary

Extend Rust's pattern matching exhaustiveness checks to cover the integer types: `u8`, `u16`, `u32`, `u64`, `u128`, `usize`, `i8`, `i16`, `i32`, `i64`, `i128`, `isize` and `char`.
varkor marked this conversation as resolved.
Show resolved Hide resolved

```rust
fn matcher_full(x: u8) {
match x { // ok
0 .. 32 => { /* ... */ }
32 => { /* ... */ }
33 ..= 255 => { /* ... */ }
}
}

fn matcher_incomplete(x: u8) {
match x { //~ ERROR: non-exhaustive patterns: `32u8...255u8` not covered
0 .. 32 => { /* ... */ }
}
}
```

# Motivation
[motivation]: #motivation

This is viewed essentially as a bug fix: other than the implementational challenges, there is no reason not to perform correct exhaustiveness checking on integer patterns, especially as range patterns are permitted, making it very straightforward to provide patterns covering every single integer.

This change will mean that Rust correctly performs exhaustiveness checking on all the types that currently compose its type system.

This feature has already [been implemented](https://github.com/rust-lang/rust/pull/50912) behind the feature flag `exhaustive_integer_patterns`, so this RFC is viewed as a motion to stabilise the feature.

# Guide-level explanation
[guide-level-explanation]: #guide-level-explanation

Exhaustive pattern matching works for integer types, just like any other type. In addition, missing ranges of integers will be reported as errors.

```rust
fn matcher_full(x: u8) {
match x { // ok
0 .. 32 => { /* ... */ }
32 => { /* ... */ }
33 ..= 255 => { /* ... */ }
}
}

fn matcher_incomplete(x: u8) {
match x { //~ ERROR: non-exhaustive patterns: `32u8...255u8` not covered
0 .. 32 => { /* ... */ }
}
}
```

More examples may be found in [the file of test cases](https://github.com/rust-lang/rust/pull/50912/files#diff-8809036e5fb5a9a0fcc283431046ef51).

# Reference-level explanation
[reference-level-explanation]: #reference-level-explanation

The implementation of this features uses interval arithmetic and an extension of the pattern matching exhaustiveness checks as described in [this paper](http://moscova.inria.fr/~maranget/papers/warn/index.html).

This feature has already [been implemented](https://github.com/rust-lang/rust/pull/50912), so the code there may be used for further reference. The source contains detailed comments about the implementation.

# Drawbacks
[drawbacks]: #drawbacks

There is no reason not to do this: it fixes a limitation of the existing pattern exhaustiveness checks.

# Rationale and alternatives
[rationale-and-alternatives]: #rationale-and-alternatives

This is a straightforward extension of the existing exhaustiveness checks. This is the only sensible design for the feature.

# Prior art
[prior-art]: #prior-art

As far as the author is unaware, Rust is the first language to support exhaustive integer pattern matching. At the time of writing, Swift and OCaml, two languages for which this feature could also make sense, do not implement this extension. This is likely because the feature is not simple to implement and the usefulness of this feature appears in specific domains.

# Unresolved questions
[unresolved-questions]: #unresolved-questions

This feature is already implemented and appears to meet expectations for such a feature, as there have been no issues brought up about the implementation or design.

# Future possibilities
[future-possibilities]: #future-possibilities

Having added exhaustive pattern matching for integers, all types in Rust for which exhaustive matching is sensible are matched exhaustively. We should aim to ensure this remains the case. However, at present, exhaustive pattern matching in Rust is viewed complete.