Attribute Macro impl_tools::autoimpl

source · []
#[autoimpl]
Expand description

A variant of the standard derive macro

This macro is similar to #[derive(Trait)], but with a few differences.

If using autoimpl and derive macros with Rust < 1.57.0, the autoimpl attribute must come first (see rust#81119).

Unlike derive, autoimpl is not extensible by third-party crates. The “trait names” provided to autoimpl are matched directly, unlike derive(...) arguments which are paths to proc_macro_derive instances. Without language support for this there appears to be no option for third-party extensions.

Bounds on generic parameters

If a type has generic parameters, generated implementations will assume the same parameters and bounds as specified in the type, but not additional bounds for the trait implemented.

Additional bounds may be specified via a where clause. A special predicate is supported: T: trait; here trait is replaced the name of the trait being implemented.

Multi-field traits

Some trait implementations make use of all fields (except those ignored):

  • Clone — implements std::clone::Clone; ignored fields are initialised with Default::default()
  • Debug — implements std::fmt::Debug; ignored fields are not printed
  • Default — implements std::default::Default using Default::default() for all fields (see also impl_default)

Parameter syntax

ParamsMulti :
   ( Trait ),+ Ignores? WhereClause?

Ignores :
   ignore ( self . Member ),+

WhereClause :
   where ( WherePredicate ),*

Examples

Implement std::fmt::Debug, ignoring the last field:

#[autoimpl(Debug ignore self.f)]
struct PairWithFn<T> {
    x: f32,
    y: f32,
    f: fn(&T),
}

Implement Clone and Debug on a wrapper, with the required bounds:

#[autoimpl(Clone, Debug where T: trait)]
struct Wrapper<T>(pub T);

Note: T: trait is a special predicate implying that for each implementation the type T must support the trait being implemented.

Single-field traits

Other traits are implemented using a single field (for structs):

  • Deref — implements std::ops::Deref
  • DerefMut — implements std::ops::DerefMut

Parameter syntax

ParamsSingle :
   ( Trait ),+ Using WhereClause?

Using :
   using self . Member

Examples

Implement Deref and DerefMut, dereferencing to the given field:

#[autoimpl(Deref, DerefMut using self.0)]
struct MyWrapper<T>(T);

Trait re-implementations

User-defined traits may be implemented over any type supporting Deref (and if required DerefMut) to another type supporting the trait.

Parameter syntax

ParamsTrait :
   for Generics ( Type ),+ Definitive? WhereClause?

Generics :
   < ( GenericParam ) >

Definitive :
   using Type

Examples

Implement MyTrait for &T, &mut T and Box<dyn MyTrait>:

#[autoimpl(for<'a, T: trait + ?Sized> &'a T, &'a mut T, Box<T>)]
trait MyTrait {
    fn f(&self) -> String;
}

Note that the first parameter bound like T: trait is used as the definitive type (required). For example, here, f is implemented with the body <T as MyTrait>::f(self).

Note further: if the trait uses generic parameters itself, these must be introduced explicitly in the for<..> parameter list.