Attribute Macro impl_self

Source
#[impl_self]
Expand description

Implement a type with impl Self syntax

This attribute macro supports a type (struct, enum, type alias or union) definition plus associated impl items within a mod.

Macro expansion discards the mod entirely, placing all contents into the outer scope. This simplifies privacy rules in many use-cases, and highlights that the usage of mod is purely a hack to make the macro input valid Rust syntax (and thus compatible with rustfmt).

§Syntax

ImplSelf :
   #[impl_self] mod Name { ScopeItem ItemImpl * }

ScopeItem :
   ItemEnum | ItemStruct | ItemType | ItemUnion

Here, ItemEnum, ItemStruct, ItemType and ItemUnion are enum, struct, type alias and union definitions respectively. Whichever of these is used, it must match the module name Name.

ItemImpl is an impl item. It may use the standard implementation syntax (e.g. impl Debug for MyType { .. }) or impl Self syntax (see below).

The mod may not contain any other items, except doc items (documentation on the module itself is ignored in favour of documentation on the defined type) and attributes (which apply as usual).

§impl Self syntax

impl Self “syntax” is syntactically-valid (but not semantically-valid) Rust syntax for writing inherent and trait impl blocks:

  • impl Self { ... } — an inherent impl item on the defined type
  • impl Debug for Self { ... } — a trait impl item on the defined type

Generic parameters and bounds are copied from the type definition. Additional generic parameters may be specified; these extend the list of generic parameters on the type itself, and thus must have distinct names. Additional bounds (where clauses) may be specified; these extend the list of bounds on the type itself.

§Example

#[impl_tools::impl_self]
mod Pair {
    /// A pair of values of type `T`
    pub struct Pair<T>(T, T);

    impl Self {
        pub fn new(a: T, b: T) -> Self {
            Pair(a, b)
        }
    }

    impl Self where T: Clone {
        pub fn splat(a: T) -> Self {
            let b = a.clone();
            Pair(a, b)
        }
    }
}