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
— implementsstd::clone::Clone
; ignored fields are initialised withDefault::default()
Debug
— implementsstd::fmt::Debug
; ignored fields are not printedDefault
— implementsstd::default::Default
usingDefault::default()
for all fields (see alsoimpl_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
— implementsstd::ops::Deref
DerefMut
— implementsstd::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.