Why does Struct { .. } pattern match tuple struct but not vice versa?

struct A(i32);
struct B { _inner: i32 }

fn main() {
    let a = A(0);
    match a {
        A { .. } => (), // why does this work?
    }
    let b = B { _inner: 0 };
    match b {
        B(_) => (), // but this doesn't?
    }
}

(Playground)

See also Struct patterns, which doesn't seem to answer my question (unless I miss something).

1 Like

The former is allowed because you can match tuple structs based on index:

struct A(i32, i32, i32);

fn main() {
    let a = A(1, 2, 3);
    match a {
        A { 2: bar, .. } => assert_eq!(bar, 3)
    }
}

The latter isn't equivalent - B(_) is only doing a wildcard match against the first element of the tuple, not all of them. If B was defined as struct B(i32, i32, i32), B(_) would fail to compile - you'd have to do B(_, _, _) instead.

It is also possible to do B(..), but this doesn't work for structs with fields.

8 Likes

Oh I didn't know that syntax. :slightly_smiling_face:

2 Likes

For historical context, RFC 1506 introduced the ability to match structs using braced patterns regardless of their declaration style, and the ability to use numbers as field names in those patterns.

9 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.