Attributes and Conditional Compilation

#[derive(...)]

#[derive(Trait1, Trait2, ...)] is an outer attribute applied to a struct, enum, or union that instructs the compiler (or a procedural derive macro) to automatically generate impl Trait for Type blocks by inspecting the type's fields or variants. Crucially, #[derive(...)] generates an implementation that does not alter the original struct or enum definition—it appends standalone impl blocks alongside it.

Built-In Standard Library Derive Macros

Derive Macro Trait Implemented Generated Behavior
Debug std::fmt::Debug Formats struct/enum name and all fields for {:?} and {:#?}
Clone std::clone::Clone Calls .clone() on every field or active enum variant
Copy std::marker::Copy Opts into bitwise copy semantics (requires Clone and all fields : Copy)
PartialEq std::cmp::PartialEq Compares all fields (or variant discriminants + payloads) with == in declaration order
Eq std::cmp::Eq Marker asserting reflexive total equality (requires PartialEq and all fields : Eq)
PartialOrd std::cmp::PartialOrd Lexicographical comparison of fields (or variants) from top to bottom
Ord std::cmp::Ord Total lexicographical ordering (requires Eq + PartialOrd)
Hash std::hash::Hash Feeds discriminant and all fields into Hasher in declaration order
Default std::default::Default Calls Default::default() on each struct field, or selects the #[default] enum variant

Deriving Default on Enums with #[default]

Stabilized in Rust 1.62, #[derive(Default)] can be applied to an enum by marking one unit variant (a variant with no fields) with the helper attribute #[default]:

#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
enum Priority {
    Low,
    #[default]
    Normal,
    High,
    Critical,
}

#[derive(Debug, Default, PartialEq, Eq)]
struct Task {
    name: String,
    priority: Priority,
    retries: u8,
}

fn main() {
    let default_task = Task::default();
    println!("default_task: {:?}", default_task);

    // Lexicographical `Ord` on `Priority` follows variant declaration order:
    println!("Low < Normal < Critical: {}", Priority::Low < Priority::Normal && Priority::Normal < Priority::Critical);
}
default_task: Task { name: "", priority: Normal, retries: 0 }
Low < Normal < Critical: true

The Generic Bound Limitation of #[derive(...)]

When #[derive(Clone)] or #[derive(Default)] is applied to a generic type struct Wrapper<T>, the built-in derive macro conservatively generates the bound where T: Clone or where T: Default on the impl block—even if T only appears inside PhantomData<T>, Rc<T>, Arc<T>, or a function pointer fn(T) that does not actually require T to implement the trait!

What `#[derive(Clone)]` Generates on `struct Handle<T>(Arc<T>)`:
  impl<T: Clone> Clone for Handle<T> { ... }  // <-- Unnecessarily requires `T: Clone`!

Manual `impl` (Works for ALL `T`, even when `T: !Clone`):
  impl<T> Clone for Handle<T> {
      fn clone(&self) -> Self { Self(Arc::clone(&self.0)) }
  }
use std::sync::Arc;

struct NonCloneResource {
    id: u32,
}

// If we used `#[derive(Clone)]`, `SharedHandle<NonCloneResource>::clone()`
// would fail to compile because `NonCloneResource` does not implement `Clone`!
struct SharedHandle<T> {
    inner: Arc<T>,
}

impl<T> Clone for SharedHandle<T> {
    fn clone(&self) -> Self {
        Self {
            inner: Arc::clone(&self.inner),
        }
    }
}

fn main() {
    let h1 = SharedHandle {
        inner: Arc::new(NonCloneResource { id: 99 }),
    };
    let h2 = h1.clone();
    println!("cloned handle id = {}", h2.inner.id);
}
cloned handle id = 99