From 1651cec432ef47b5738057bb82bda7b0c7370b45 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Thu, 17 Apr 2014 19:26:55 +1000 Subject: [PATCH] RFC for attributes on match arms. --- active/0000-match-arm-attributes.md | 92 +++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 active/0000-match-arm-attributes.md diff --git a/active/0000-match-arm-attributes.md b/active/0000-match-arm-attributes.md new file mode 100644 index 00000000000..f1f0baa81e0 --- /dev/null +++ b/active/0000-match-arm-attributes.md @@ -0,0 +1,92 @@ +- Start Date: 2014-03-20 +- RFC PR #: (leave this empty) +- Rust Issue #: (leave this empty) + +# Summary + +Allow attributes on match arms. + +# Motivation + +One sometimes wishes to annotate the arms of match statements with +attributes, for example with conditional complilation `#[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](https://github.com/sfackler/rust-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 + +```rust +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 `match`s can only mention `Sslv2` when the `cfg` is +active, i.e. the following is invalid: + +```rust +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: + +```rust +match foo { + Common => {} + #[cold] + Rare => {} +} +``` + + +# Detailed design + +Normal attribute syntax, applied to a whole match arm. + +```rust +match x { + #[attr] + Thing => {} + + #[attr] + Foo | Bar => {} + + #[attr] + _ => {} +} +``` + +# Alternatives + +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. + +# Unresolved questions + +Nothing particularly.