パターンマッチ中の `..`

mdbookのコードを読んでいて、なんじゃこの記法は、となったコードがあったので、
理解してしまえばなんて無いことですが、しばらく悩んだし戒めのために書きます

簡略化して書くとこんなコードです

enum Enum {
    A(u8, u8, u8),
    B
}

macro_rules! some_macro {
    ($pat:pat) => {
        let e = Enum::A(0, 0, 0)
        match e {
            $pat => println!("\(^o^)/"),
            _ => panic!("panic!")
        }
    }
}


fn main() {
    some_macro!(Enum::A(..));
}

play.rust-lang.org

Enum::A(..) の部分に引っかかりました。
Enum::Aは引数を3つとるのでは・・・?としばらく悩んだのですが、
マクロを展開してしまえば

        let e = Enum::A(0, 0, 0)
        match e {
            Enum::A(..) => println!("\(^o^)/"),
            _ => panic!("panic!")
        }

ということですね。
パターンマッチ中はいちいち Enum::A(_, _, _) などと書かなくても (..)で省略できるんですね。
ちゃんとここに書いてありました。

github.com

    let (.., x) = (0, 0, 0, 0, 0, 0, 0, 0, 1);
    println!("x: {}", x); // => x: 1

    let (y, ..) = (1, 0, 0, 0, 0, 0, 0, 0, 0);
    println!("y: {}", y); // => y: 1

    let (a, .., b) = (1, 0, 0, 0, 0, 0, 0, 0, 2);
    println!("a: {}, b: {}", a, b); // => a: 1, b: 2

play.rust-lang.org

と同じセマンティクスですね。

Rust便利ですね。

Ruby*args **argsで配列やハッシュで可変長の引数を取れるのとか、Ruby2.7のパターンマッチの*と似てますね。似てないか。

ちなみに僕が悩んだ元のコードは

mdBook/summary.rs at a592da33bbf0adbe93d7d47fd016a8af462ed677 · rust-lang-nursery/mdBook · GitHub これです。