mozilla/rust — pull request #8258 by huonw (2013-08-03 07:45:20+00:00)
Title: Deriving options & general clean-up

This adds the infrastructure to allow `#[deriving]` to take options (closes https://github.com/mozilla/rust/issues/7229), e.g.

```rust
#[deriving(Eq(ignore(a)))]
struct Foo {
a: int,
b: uint
}
```

It also implements three options for the comparison traits `test_order`, `ignore` and `reverse`, e.g.:

```rust
#[deriving(Eq(test_order(y), ignore(z, w)),
TotalOrd(reverse(x)))]
struct Foo {
x: uint,
y: uint,
z: uint,
w: uint
}
```

which means that the field `y` is tested first, `z` and `w` aren't tested at all (for `Eq`), and `x` is sorted in reverse order for `TotalOrd`.

For the comparison traits, the options are strictly checked; it is an error to:
- specify anything other than the those that the trait supports (all support `test_order`, `Eq` & `Ord` support `ignore`, and `Ord` & `TotalOrd` support `reverse`.)
- specify fields that don't exist
- use a format different to `Trait(option(bar, baz))`
- use any of these options on enums or tuple structs: only structs with named fields.

(This also adds documentation to the manual about this.)

At the moment, all other traits emit a warning if any options are used (and ignore them).

(In general, all forms of options are supported, e.g. `#[deriving(Foo="bar")]` works too.)

Also, some general clean-up relating to `deriving`:
- `TotalOrd` was too eager, and evaluated the `.cmp` call for every field, even if it could short-circuit earlier.
- the pointer types didn't have impls for `TotalOrd` or `TotalEq`.