rust-lang / rust-lang/rfcs

allow slice patterns to match non-fixed/generic length arrays

Open
#3,675 6 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Markdown
Stars
6.6k
Forks
1.7k
Avg merge
16h 14m
Merged PRs (30d)
1

Description

Currently slice patterns can match fixed sized arrays and dynamic sized slices. It would be useful in code over generic length array to also be able to match on dynamic sized/non-fixed length/generic length arrays.

fn example<const N: usize>(arr: /* &[u8; N] | &mut [u8; N] | */ [u8; N]) {
    match arr {
        [] => {
            println!("None");
        }
        [_] => {
            println!("Some");
        }
        [_,_,_rest@..] => {
            println!("Many");
        }
    }
}

play-ground

Currently this results in E7030 and E0308

   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
  --> src/main.rs:14:9
   |
14 |         [] => {
   |         ^^ expected `0`, found `N`
   |
   = note: expected array `[u8; 0]`
              found array `[u8; N]`

error[E0308]: mismatched types
  --> src/main.rs:17:9
   |
17 |         [_] => {
   |         ^^^ expected `1`, found `N`
   |
   = note: expected array `[u8; 1]`
              found array `[u8; N]`

error[E0730]: cannot pattern-match on an array without a fixed length
  --> src/main.rs:20:9
   |
20 |         [_,_,..] => {
   |         ^^^^^^^^

Some errors have detailed explanations: E0308, E0730.
For more information about an error, try `rustc --explain E0308`.
error: could not compile `playground` (bin "playground") due to 3 previous errors

For arrays behind references one can mostly workaround this by turning the array reference into a slice reference.

fn example<const N: usize>(arr: /*  &mut [u8; N] | */ &[u8; N]) {
   let slice : &[_] = arr;
    match slice {
        [] => {
            println!("None");
        }
        [_] => {
            println!("Some");
        }
        [_,_,_rest@..] => {
            println!("Many");
        }
    }
}

But this leaves out the owned case and for arrays I would expect sub-array patterns to be arrays rather than slices, i.e. for input type &[u8;N] the type of _rest for the first example would be &[u8;N - 2] rather than &[u8].

For exhaustiveness checking generic arrays would be treated like slices i.e. all lengths (0..=usize::MAX) needs to be covered.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Rust Reference's slice-pattern section and reproduce the linked Playground example, including errors E0730 and E0308. Define how generic-length arrays, owned and referenced values, sub-array bindings, and exhaustiveness should behave; done means the feature's semantics are specified clearly enough for an RFC or implementation plan.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
compilers
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.