Skip to content

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

@Skgland

Description

@Skgland

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions