impl_scope!() { /* proc-macro */ }
Expand description

Implement a type with impl Self syntax

This macro facilitates definition of a type (struct, enum or union) plus implementations via impl Self { .. } syntax: Self is expanded to the type’s name, including generics and bounds (as defined on the type).

Caveat: rustfmt can not yet format contents (see rustfmt#5254, rustfmt#5538).

Special attribute macros

Additionally, impl_scope! supports special attribute macros evaluated within its scope:

  • #[impl_default]: implement Default using field initializers (which are not legal syntax outside of impl_scope!)

Note: matching these macros within impl_scope! does not use path resolution. Using #[impl_tools::impl_default] would resolve the variant of this macro which doesn’t support field initializers.

Syntax

ImplScope :
   impl_scope! { ScopeItem ItemImpl * }

ScopeItem :
   ItemEnum | ItemStruct | ItemType | ItemUnion

That is, one type definition followed by a set of implementations. Impls must take one of two forms:

  • impl Self { ... } — generic parameters and bounds of the type are used
  • impl MyType { ... } where MyType matches the name of the defined type

Generic parameters from the type are included implicitly with the first form. Additional generic parameters and where clauses are supported (parameters and bounds are merged).

Example

impl_tools::impl_scope! {
    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)
        }
    }
}