Default Methods & Supertraits
Traits may ship default method bodies and require supertraits (trait B: A) so implementors provide prerequisite behavior.
Search across all documentation pages
Traits may ship default method bodies and require supertraits (trait B: A) so implementors provide prerequisite behavior.
trait Animal: std::fmt::Display {
fn name(&self) -> &str;
fn describe(&self) -> String {
format!("{} is a {}", self.name(), self)
}
}When to reach for this: DRY for shared trait logic and layering traits (Display before custom summary).
struct Cat(&'static str);
impl std::fmt::Display for Cat {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "cat")
}
}
impl Animal for Cat {
fn name(&self) -> &str { self.0 }
}
fn main() {
let c = Cat("Milo");
println!("{}", c.describe());
}What this demonstrates:
describe calls name and DisplayDisplay bound on Animalimpl Animal when defaults sufficeDefault methods are inherited unless overridden. Supertraits compose capability: trait Iterator: IntoIterator style hierarchies (conceptually).
impl site. Fix: Implement Display (etc.) first.dyn. Fix: Check object safety rules.| Alternative | Use When | Don't Use When |
|---|---|---|
| Helper functions | No trait polymorphism | Behavior shared across trait impls |
| Blanket impl | Auto impl for all T: Bound | Conflicting impl hazard |
| Extension trait | Add to existing type | Orphan rule |
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Reviewed by Chris St. John·Last updated Jul 16, 2026