Skip to content

Refutable slice pattern with let produces a possibly misleading diagnostic for &[T; N] and a much better diagnostic with &[T] #97430

Open
@saethlin

Description

@saethlin

I just saw someone write this code:

fn main() {
    let x = &[];
    let Some([val,..]) = Some(x);
}

which produces this diagnostic:

error[E0528]: pattern requires at least 1 element but array has 0
 --> src/main.rs:3:14
  |
3 |     let Some([val,..]) = Some(x);
  |              ^^^^^^^^ pattern cannot match array of 0 elements

and they then used this message to misunderstand the implications of slice patterns, perhaps thinking that this code would somehow panic at runtime. Changing the type of x to a slice like so:

fn main() {
    let x: &[u8] = &[];
    let Some([val,..]) = Some(x);
}

produces a better diagnostic which mentions the much deeper problem with this construction: The pattern is refutable on two accounts (the Option and the slice length). The diagnostic only mentions one, but I'd still prefer to see this in the former case:

error[E0005]: refutable pattern in local binding: `None` not covered
   --> src/main.rs:3:9
    |
3   |     let Some([val,..]) = Some(x);
    |         ^^^^^^^^^^^^^^ pattern `None` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
note: `Option<&[u8]>` defined here
    = note: the matched value is of type `Option<&[u8]>`
help: you might want to use `if let` to ignore the variant that isn't matched
    |
3   |     let val = if let Some([val,..]) = Some(x) { val } else { todo!() };
    |     ++++++++++++                              ++++++++++++++++++++++++

rustc 1.61.0 (fe5b13d68 2022-05-18)

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-slice-patternsArea: Slice patterns, https://github.com/rust-lang/rust/issues/23121D-newcomer-roadblockDiagnostics: Confusing error or lint; hard to understand for new users.D-terseDiagnostics: An error or lint that doesn't give enough information about the problem at hand.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions