Trait Bounds
Bounds constrain generic parameters so code can call trait methods safely: T: Display, where clauses, and multiple bounds with +.
Search across all documentation pages
Bounds constrain generic parameters so code can call trait methods safely: T: Display, where clauses, and multiple bounds with +.
use std::fmt::Display;
fn print_all<T: Display>(items: &[T]) {
for item in items {
println!("{item}");
}
}
fn compare<T>(a: T, b: T) -> T
where
T: PartialOrd,
{
if a > b { a } else { b }
}When to reach for this: Any generic function using trait methods; prefer where for readable complex bounds.
use std::fmt::{Debug, Display};
fn report<T>(value: T) -> String
where
T: Debug + Display,
{
format!("user sees {value}, debug {value:?}")
}
fn main() {
println!("{}", report(42));
}What this demonstrates:
Debug + Displaywhere clause separates bounds from signatureTimpl Trait sugarfn f(x: impl Display) == fn f<T: Display>(x: T) for one parameter.
for<'a> for fns needing any lifetime - advanced with Fn traits.
T: 'a - values in T cannot borrow shorter than 'a.
T. Fix: Add trait to bound list.where clause explosion - Unreadable. Fix: Type aliases type SerializeMap = ....impl Trait in return not object-safe mix - Cannot return different impl Trait types. Fix: Enum or Box<dyn Trait>.| Alternative | Use When | Don't Use When |
|---|---|---|
dyn Trait parameter | Heterogeneous inputs | Generics faster |
| Concrete types | Single use | Library reuse |
| Enum of capabilities | Closed options | Open trait set |
| Macros | Generate bounded fns | Bounds expressible |
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