Attribute Macro impl_tools::autoimpl
source · [−]#[autoimpl]
Expand description
A variant of the standard derive
macro
#[autoimpl]
may be used in two ways:
- On a type definition, to implement a specified trait (like
#[derive]
) - On a trait definition, to re-implement that trait for a specified type
supporting
Deref
If using autoimpl
and derive
macros with Rust < 1.57.0, the
autoimpl
attribute must come first (see rust#81119).
Trait implementation
Name | Path | ignore | using |
---|---|---|---|
Clone | ::std::clone::Clone | initialized with Default::default() | - |
Debug | ::std::fmt::Debug | field is not printed | - |
Default | ::std::default::Default | - | - |
Deref | ::std::ops::Deref | - | deref target |
DerefMut | ::std::ops::DerefMut | - | deref target |
Note: impl_default
is a more flexible alternative to Default
.
Ignore: trait supports ignoring fields (e.g. #[autoimpl(Debug ignore self.foo)]
).
Using: trait requires a named field to “use”. Example:
#[autoimpl(Deref using self.foo)]
implements Deref
to return (a
reference to) field self.foo
.
Traits are matched according to the path, via one of three forms:
- Only the last component, e.g.
#[autoimpl(Clone)]
- The full path except leading
::
, e.g.#[autoimpl(std::clone::Clone)]
- The full path with leading
::
, e.g.#[autoimpl(::std::clone::Clone)]
Note regarding no_std
usage: the above table is wrong in that traits use
paths in core
or alloc
, but also match std
. That is,
#[autoimpl(std::clone::Clone)]
and #[autoimpl(core::clone::Clone)]
are
equivalent and generate an impl for ::core::clone::Clone
.
Parameter syntax
ParamsMulti :
( Trait ),+ Using? Ignores? WhereClause?Using :
using
self
.
MemberIgnores :
ignore
(self
.
Member ),+WhereClause :
where
( WherePredicate ),*
Generics and where clause
Type generics are inherited from the type definition. Bounds defined by the
type are inherited, but unlike #[derive]
no additional bounds for the
trait being implemented are assumed.
A where
clause, e.g. where T: Foo
, may be used.
A special bound syntax, T: trait
, indicates that T
must support the
trait being implemented.
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);
Implement Deref
and DerefMut
, dereferencing to the given field:
#[autoimpl(Deref, DerefMut using self.1)]
struct AnnotatedWrapper<T>(String, T);
Trait re-implementation
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.