Rust’s standard library defines a set of traits that types opt into to gain shared behaviour — formatting, cloning, comparison, iteration, conversion. Many can be derived; others must be written by hand. This tool is a searchable reference covering each trait’s required methods, derive support, and blanket implementations.
Why standard traits matter more in Rust than in most languages
In Rust, traits are the primary mechanism for generic programming. Unlike interface inheritance in OOP languages, traits compose without hierarchy: a type can implement Display, From<String>, and Iterator independently, and generic code can demand any combination of them. The standard library’s core traits are the vocabulary that makes this work — they let you use HashMap (requires Hash + Eq), sort a Vec (requires Ord), format a value with {} (requires Display), or write generic into() calls (requires From). Understanding which traits are required for each use case is a significant part of writing idiomatic Rust.
How it works
A trait declares method signatures; an impl Trait for Type block supplies
them. Some methods are required (you must provide them) and some are
provided (default implementations you may override). The reference notes,
for each trait:
- Required methods — the minimum you must implement.
- Derivable — whether
#[derive(...)]can generate the impl when all fields cooperate. - Blanket impls — automatic implementations, such as
IntofromFrom, orToStringfromDisplay.
Worked example
#[derive(Debug, Clone, PartialEq, Eq, Hash, Default)]
struct Point { x: i32, y: i32 }
// Display cannot be derived — write it by hand:
use std::fmt;
impl fmt::Display for Point {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
// From gives Into for free via a blanket impl:
impl From<(i32, i32)> for Point {
fn from((x, y): (i32, i32)) -> Self { Point { x, y } }
}
let p: Point = (1, 2).into(); // Into<Point> exists automatically
Which traits do standard containers need?
| Use case | Required traits |
|---|---|
HashMap<K, V> key | Hash + Eq |
BTreeMap<K, V> key | Ord (implies Eq + PartialOrd + PartialEq) |
Vec::sort() | Ord |
println!("{}", val) | Display |
println!("{:?}", val) | Debug |
let b = a.clone() | Clone |
let b = a without move | Copy (implies Clone) |
Generic into() call | From on the destination |
Notes
- Implementing
Displayautomatically gives youToString(and thus.to_string()) through a blanket impl — never implementToStringdirectly. Eq,Ord, andHashare consistency-marker contracts: deriving them keeps==, ordering, and hashing in agreement, whichHashMap/BTreeMaprely on.Dropcannot be derived and cannot be called manually; the compiler invokes it when a value goes out of scope. Usestd::mem::dropto drop early.Derefpowers smart pointers likeBoxandRc; abusing it for inheritance is discouraged.- A type can be
PartialOrdwithout beingOrd— floats are the classic example, becauseNaN != NaNbreaks total ordering. This is why sorting aVec<f64>requiressort_byrather thansort. Copyis a marker trait with no methods: the compiler copies the bits on assignment. Once a type owns a heap allocation (String,Vec,Box), it cannot beCopy.