Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

摘要

Allow attributes on match arms.

動機

One sometimes wishes to annotate the arms of match statements with attributes, for example with conditional compilation #[cfg]s or with branch weights (the latter is the most important use).

For the conditional compilation, the work-around is duplicating the whole containing function with a #[cfg]. A case study is sfackler’s bindings to OpenSSL, where many distributions remove SSLv2 support, and so that portion of Rust bindings needs to be conditionally disabled. The obvious way to support the various different SSL versions is an enum

pub enum SslMethod {
    #[cfg(sslv2)]
    /// Only support the SSLv2 protocol
    Sslv2,
    /// Only support the SSLv3 protocol
    Sslv3,
    /// Only support the TLSv1 protocol
    Tlsv1,
    /// Support the SSLv2, SSLv3 and TLSv1 protocols
    Sslv23,
}

However, all matchs can only mention Sslv2 when the cfg is active, i.e. the following is invalid:

fn name(method: SslMethod) -> &'static str {
    match method {
        Sslv2 => "SSLv2",
        Sslv3 => "SSLv3",
        _ => "..."
    }
}

A valid method would be to have two definitions: #[cfg(sslv2)] fn name(...) and #[cfg(not(sslv2)] fn name(...). The former has the Sslv2 arm, the latter does not. Clearly, this explodes exponentially for each additional cfg’d variant in an enum.

Branch weights would allow the careful micro-optimiser to inform the compiler that, for example, a certain match arm is rarely taken:

match foo {
    Common => {}
    #[cold]
    Rare => {}
}

詳細設計

Normal attribute syntax, applied to a whole match arm.

match x {
    #[attr]
    Thing => {}

    #[attr]
    Foo | Bar => {}

    #[attr]
    _ => {}
}

替代方案

There aren’t really any general alternatives; one could probably hack around matching on conditional enum variants with some macros and helper functions to share as much code as possible; but in general this won’t work.

未解決的問題

Nothing particularly.