[FR] `var @` syntax in `match` does not refined the type of `var`


#1

This is a FR – feature request

The type of punct will not be refined to TokenTree::Punct in the body of the branch – { } after =>.

fn split_token_stream (
    token_stream: TokenStream,
    punct_ch: char,
) -> Vec <Vec <TokenTree>> {
    let mut result: Vec <Vec <TokenTree>> = Vec::new ();
    let mut vec: Vec <TokenTree> = Vec::new ();
    for token in token_stream .into_iter () {
        match token {
            punct @ TokenTree::Punct { .. }
            if punct_ch == punct.as_char () => {
                unimplemented! ()
            }
            _ => {
                unimplemented! ()
            }
        }
    }
    result
}


#2

The above snippet doesn’t do what you want it to do.

match token {
    TokenTree::Punct(punct)
    if punct_ch == punct.as_char() => {
        unimplemented!()
    }
    _ => { unimplemented!() }
}

name @ pat binds name to the entire pattern, so here token is moved into punct. By writing it as above, you get the Punct in punct instead of the TokenTree.

I’m surprised this example even compiles (if it does), as TokenTree::Punct is a newtype variant, not a struct variant.

Full refinement typing for enum variants is a long way from happening in design as well as implementation. Currently, enum variants aren’t even types, so I’m unsure whether it can even be added.


#3

Thanks!

I forgot that enum variants aren’t even types. Hope they will be in the future.