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

Pattern matching on fixed length vectors should not be refutable #7784

Closed
brendanzab opened this issue Jul 14, 2013 · 4 comments
Closed

Pattern matching on fixed length vectors should not be refutable #7784

brendanzab opened this issue Jul 14, 2013 · 4 comments
Labels
A-typesystem Area: The type system

Comments

@brendanzab
Copy link
Member

The length of fixed length vectors does not change, so a single pattern should be considered exhaustive.

Function argument destructuring:

fn foo<T>([x, y, z]: [T,..3]) -> (T, T, T) { (x, y, z) }
<anon>:7:19: 7:28 error: refutable pattern in function argument
<anon>:7          fn foo<T>([x, y, z]: [T,..3]) -> (T, T, T) { (x, y, z) }
                           ^~~~~~~~~

Let destructuring:

let [x, y, z] = [1, 2, 3]; 
<anon>:7:13: 7:22 error: refutable pattern in local binding
<anon>:7          let [x, y, z] = [1, 2, 3];
                     ^~~~~~~~~

Match patterns:

match [1, 2, 3] { [x, y, z] => (x, y, z) }
<anon>:7:9: 7:51 error: non-exhaustive patterns: vectors of length 0 not covered
<anon>:7          match [1, 2, 3] { [x, y, z] => (x, y, z) }
                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@jdm
Copy link
Contributor

jdm commented Jul 15, 2013

See also #5520.

@bstrie
Copy link
Contributor

bstrie commented Jul 15, 2013

Additionally, all of these should work for any fixed length greater than zero:

fn foo<T>([head, ..tail]: [T,..3]) -> (T, [T]) { (head, tail) }
let [head, ..tail] = [1, 2, 3]; 
match [1, 2, 3] { [head, ..tail] => (head, tail) }

Also consider any other permutation where the .. is allowed, such as [first, ..middle, penultimate, ultimate] and so on (which would only work on sizes of 3 and greater).

@huonw
Copy link
Member

huonw commented Jan 12, 2014

We now consider fixed length vector patterns to be irrefutable in match, but not in let. The following compiles fine, but the commented out parts hit error: refutable pattern in local binding:

fn main() {
    let x = [1, 2, 3];

    match x {
        [_a, _b, _c] => {}
    }
    match x {
        [_a, .. _b] => {}
    }
    match x {
        [_a, .. _b, _c] => {}
    }

    /*
    let [_a, _b, _c] = x;
    let [_a, .. _b] = x;
    let [_a, .. _b, _c] = x;
    */
}

@ghost
Copy link

ghost commented May 31, 2014

One way to go about this would be to check let refutability the same way exhaustiveness is checked in patterns. But I worry the perf impact might be significant.

@bors bors closed this as completed in 1e68d57 Jun 21, 2014
nrc pushed a commit to nrc/rust that referenced this issue Aug 22, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-typesystem Area: The type system
Projects
None yet
Development

No branches or pull requests

4 participants