Module syntax::ext::deriving::generic[src]

Some code that abstracts away much of the boilerplate of writing deriving instances for traits. Among other things it manages getting access to the fields of the 4 different sorts of structs and enum variants, as well as creating the method and impl ast instances.

Supported features (fairly exhaustive):

Unsupported: FIXME #6257: calling methods on reference fields, e.g. deriving Eq/Ord/Clone don't work on struct A(&int), because of how the auto-dereferencing happens.

The most important thing for implementers is the Substructure and SubstructureFields objects. The latter groups 5 possibilities of the arguments:

In the first two cases, the values from the corresponding fields in all the arguments are grouped together. In the EnumNonMatching case this isn't possible (different variants have different fields), so the fields are grouped by which argument they come from. There are no fields with values in the static cases, so these are treated entirely differently.

The non-static cases have Option<ident> in several places associated with field exprs. This represents the name of the field it is associated with. It is only not None when the associated field has an identifier in the source code. For example, the xs in the following snippet

struct A { x : int }

struct B(int);

enum C {
    C0(int),
    C1 { x: int }
}

The ints in B and C0 don't have an identifier, so the Option<ident>s would be None for them.

In the static cases, the structure is summarised, either into the just spans of the fields or a list of spans and the field idents (for tuple structs and record structs, respectively), or a list of these, for enums (one for each variant). For empty struct and empty enum variants, it is represented as a count of 0.

Examples

The following simplified PartialEq is used for in-code examples:

trait PartialEq {
    fn eq(&self, other: &Self);
}
impl PartialEq for int {
    fn eq(&self, other: &int) -> bool {
        *self == *other
    }
}

Some examples of the values of SubstructureFields follow, using the above PartialEq, A, B and C.

Structs

When generating the expr for the A impl, the SubstructureFields is

Struct(~[FieldInfo {
           span: <span of x>
           name: Some(<ident of x>),
           self_: <expr for &self.x>,
           other: ~[<expr for &other.x]
         }])

For the B impl, called with B(a) and B(b),

Struct(~[FieldInfo {
          span: <span of `int`>,
          name: None,
          <expr for &a>
          ~[<expr for &b>]
         }])

Enums

When generating the expr for a call with self == C0(a) and other == C0(b), the SubstructureFields is

EnumMatching(0, <ast::Variant for C0>,
             ~[FieldInfo {
                span: <span of int>
                name: None,
                self_: <expr for &a>,
                other: ~[<expr for &b>]
              }])

For C1 {x} and C1 {x},

EnumMatching(1, <ast::Variant for C1>,
             ~[FieldInfo {
                span: <span of x>
                name: Some(<ident of x>),
                self_: <expr for &self.x>,
                other: ~[<expr for &other.x>]
               }])

For C0(a) and C1 {x} ,

EnumNonMatching(~[(0, <ast::Variant for B0>,
                   ~[(<span of int>, None, <expr for &a>)]),
                  (1, <ast::Variant for B1>,
                   ~[(<span of x>, Some(<ident of x>),
                      <expr for &other.x>)])])

(and vice versa, but with the order of the outermost list flipped.)

Static

A static method on the above would result in,

StaticStruct(<ast::StructDef of A>, Named(~[(<ident of x>, <span of x>)]))

StaticStruct(<ast::StructDef of B>, Unnamed(~[<span of x>]))

StaticEnum(<ast::EnumDef of C>, ~[(<ident of C0>, <span of C0>, Unnamed(~[<span of int>])),
                                  (<ident of C1>, <span of C1>,
                                   Named(~[(<ident of x>, <span of x>)]))])

Modules

ty

A mini version of ast::Ty, which is easier to use, and features an explicit Self type to use when specifying impls to be derived.

Structs

FieldInfo

Summary of the relevant parts of a struct/enum field.

MethodDef
Substructure

All the data about the data structure/method being derived upon.

TraitDef

Enums

StaticFields

Fields for a static method

SubstructureFields

A summary of the possible sets of fields. See above for details and examples

Functions

combine_substructure
cs_and

cs_binop with binop == and

cs_binop

Use a given binop to combine the result of calling the derived method on all the fields.

cs_fold

Fold the fields. use_foldl controls whether this is done left-to-right (true) or right-to-left (false).

cs_or

cs_binop with binop == or

cs_same_method

Call the method that is being derived on all the fields, and then process the collected results. i.e.

cs_same_method_fold

Fold together the results of calling the derived method on all the fields. use_foldl controls whether this is done left-to-right (true) or right-to-left (false).

Type Definitions

CombineSubstructureFunc

Combine the values of all the fields together. The last argument is all the fields of all the structures, see above for details.

EnumNonMatchFunc

Deal with non-matching enum variants, the arguments are a list representing each variant: (variant index, ast::Variant instance, [variant fields]), and a list of the nonself args of the type