Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The #[derive] attribute is a built-in compiler attribute in Rust used to invoke procedural derive macros, which automatically generate trait implementations for user-defined data structures (structs, enums, and unions). At compile time, the compiler passes the TokenStream of the annotated item to the specified derive macro. The macro itself parses these tokens (often into an Abstract Syntax Tree), generates the corresponding impl blocks, and returns a new TokenStream that the compiler expands into the final program.
#[derive(Clone, Debug)]
struct DataStructure {
    field: String,
}

Mechanics of Code Expansion

When the Rust compiler encounters a #[derive] attribute, it acts as a dispatcher. It does not natively understand the traits being derived; instead, it hands the token stream of the struct, enum, or union to the corresponding macro. For example, applying #[derive(Debug)]:
#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}
During the macro expansion phase, the Debug derive macro processes the tokens of Point and synthesizes an implementation conceptually identical to this:
impl std::fmt::Debug for Point {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Point")
         .field("x", &self.x)
         .field("y", &self.y)
         .finish()
    }
}

Trait Bounds and Field Requirements

The #[derive] attribute itself enforces no structural requirements on the annotated type. Because it merely delegates to a procedural macro, the rules for successful derivation are dictated entirely by the specific macro’s implementation. Custom derives can generate implementations regardless of the types of the constituent fields. While many built-in macros (such as Clone or Debug) generally require all constituent fields to implement the target trait, this is not a universal rule. For instance, applying #[derive(Default)] to an enum only requires the fields of the specific variant annotated with #[default] to implement Default; the fields of other variants are ignored. When applying built-in #[derive] macros to generic types, the macro typically infers and applies the necessary trait bounds to the generic parameters automatically.
#[derive(Clone)]
struct Wrapper<T> {
    inner: T,
}
The built-in Clone macro expands this by applying the Clone bound to the generic parameter T:
impl<T: Clone> Clone for Wrapper<T> {
    fn clone(&self) -> Self {
        Wrapper {
            inner: self.inner.clone(),
        }
    }
}

Standard Library Derivable Traits

The Rust standard library provides built-in derive macros for a specific set of core traits, categorized by their operational semantics:
  • Equivalence and Comparison: PartialEq, Eq, PartialOrd, Ord
  • Memory Duplication: Clone, Copy
  • Formatting: Debug
  • Initialization: Default
  • Hashing: Hash

Custom Derive Macros

The #[derive] system is extensible via Rust’s procedural macro system (proc_macro). Library authors can define custom derive macros by annotating a public function with #[proc_macro_derive(TraitName)].
extern crate proc_macro;
use proc_macro::TokenStream;

#[proc_macro_derive(MyCustomTrait)]
pub fn my_custom_trait_derive(input: TokenStream) -> TokenStream {
    // 1. The macro receives the TokenStream from the compiler.
    // 2. It parses the input (often using the `syn` crate).
    // 3. It generates the `impl MyCustomTrait for ...` block (often using the `quote` crate).
    // 4. It returns the generated code as a new TokenStream for the compiler to expand.
    TokenStream::new()
}
Once defined in a procedural macro crate, this custom derive can be invoked using the standard #[derive(MyCustomTrait)] syntax, functioning identically to the compiler’s built-in derives.
Master Rust with Deep Grasping Methodology!Learn More