Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC for attributes on match arms. #49

Merged
merged 1 commit into from
Apr 22, 2014
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions active/0000-match-arm-attributes.md
Original file line number Diff line number Diff line change
@@ -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.