Default Methods & Supertraits
Traits may ship default method bodies and require supertraits (trait B: A) so implementors provide prerequisite behavior.
Recipe
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).
Working Example
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:
- Default
describecallsnameandDisplay - Supertrait
Displaybound onAnimal - Minimal
impl Animalwhen defaults suffice
Deep Dive
Default methods are inherited unless overridden. Supertraits compose capability: trait Iterator: IntoIterator style hierarchies (conceptually).
Gotchas
- Missing supertrait impl - Errors at
implsite. Fix: ImplementDisplay(etc.) first. - Object safety with defaults - Some combos break
dyn. Fix: Check object safety rules. - Infinite recursion in default - Default calls itself. Fix: Call required method, not self default.
- Sealed pattern bypass - Document who may implement. Fix: Private supertrait in module.
- Breaking default changes - Semver for public traits. Fix: New trait or version bump.
Alternatives
| 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 |
FAQs
Override defaults?
Provide method in `impl` block.Multiple supertraits?
`trait T: A + B`.Default uses `Self`?
Yes - other trait methods on receiver.dyn Trait + defaults?
Works if trait object safe.Async defaults?
Modern Rust supports async fn in traits with edition support.Specialization?
Unstable - overlapping impls not in stable Rust.vs C++ virtual defaults?
Similar intent; Rust traits are not inheritance.Test defaults?
Impl minimal type, call default method only.Default visibility?
Same as trait - usually `pub` with trait.Required associated types?
Separate from defaults - must specify in impl.Related
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+.