Rust error E0277: the trait bound is not satisfied
What Rust's E0277 error means (a type doesn't implement a required trait) and how to fix its most common forms: Display, Ord, Send, ? and collect.
E0277 means some code requires a type to implement a trait, and it doesn't. It's the error behind many differently worded messages, so it helps to recognize the pattern: which type, which trait, and who requires it.
The classic form names the trait directly:
#[derive(Debug)]
struct Item {
name: String,
}
fn duplicate<T: Clone>(x: &T) -> T {
x.clone()
}
fn main() {
let sword = Item { name: String::from("sword") };
println!("{:?}", duplicate(&sword).name);
}
error[E0277]: the trait bound `Item: Clone` is not satisfied
duplicate requires T: Clone, and Item doesn't implement Clone. Fix: #[derive(Debug, Clone)].
The common forms, and their fixes
| Message | Cause | Fix |
|---|---|---|
`Point` doesn't implement `std::fmt::Display` |
{} on your type |
use {:?} or implement Display |
`Point` doesn't implement `Debug` |
{:?} without derive |
#[derive(Debug)] |
the trait bound `{float}: Ord` is not satisfied |
sort(), max(), BTreeMap key on floats |
sort_by(|a, b| a.total_cmp(b)) |
`T` doesn't implement `std::fmt::Display` |
generic function uses a trait it didn't ask for | add the bound: T: Display |
cannot add `i64` to `i32` |
mixed number types | convert one side |
the type `[i32]` cannot be indexed by `i32` |
index isn't usize |
v[i as usize] or use usize |
the `?` operator can only be used in a function that returns `Result` or `Option` |
? in main or a () function |
return a Result |
`?` couldn't convert the error to `MyError` |
no From impl for the error |
implement From, or map_err |
a value of type `Vec<i32>` cannot be built from an iterator over elements of type `&i32` |
collecting references | .copied() or .cloned() before collect |
`Rc<i32>` cannot be sent between threads safely |
Rc moved into a thread |
use Arc |
Generic code: add the bound
Inside a generic function you may only use what the bounds promise:
fn print_all<T>(items: &[T]) {
for item in items {
println!("{item}");
}
}
fn main() {
print_all(&[1, 2, 3]);
}
error[E0277]: `T` doesn't implement `std::fmt::Display`
rustc suggests the fix: "consider restricting type parameter T with trait Display", meaning fn print_all<T: std::fmt::Display>(items: &[T]).
Sorting floats
fn main() {
let mut temps = vec![21.5, 19.0, 23.25];
temps.sort();
println!("{temps:?}");
}
error[E0277]: the trait bound `{float}: Ord` is not satisfied
sort needs a total order (Ord), and floats only have a partial one because NaN isn't comparable. temps.sort_by(|a, b| a.total_cmp(b)) sorts with IEEE 754's total order.
How to read a long E0277
- Find the type and trait in the first line.
- Look for
required by a bound in ...: it names the function or impl that demands the trait. - Look at the
help:lines: rustc lists types that do implement the trait, and often the exactderiveor bound to add. - If the type is foreign and the trait is foreign (say
DisplayforVec<T>), the orphan rule stops you implementing it directly; wrap the type in a newtype.
Example
use std::fmt::Display;
#[derive(Debug, Clone, PartialEq)]
struct Item {
name: String,
price: f64,
}
fn duplicate<T: Clone>(x: &T) -> T {
x.clone()
}
fn print_all<T: Display>(items: &[T]) {
let parts: Vec<String> = items.iter().map(|i| i.to_string()).collect();
println!("{}", parts.join(" | "));
}
fn main() {
let sword = Item { name: String::from("sword"), price: 12.5 };
let copy = duplicate(&sword);
println!("{copy:?} equal: {}", copy == sword);
print_all(&[1, 2, 3]);
print_all(&["a", "b"]);
let mut temps = vec![21.5, 19.0, 23.25];
temps.sort_by(|a: &f64, b| a.total_cmp(b));
println!("{temps:?}");
let mut items = vec![copy, Item { name: String::from("potion"), price: 3.0 }];
items.sort_by(|a, b| a.price.total_cmp(&b.price));
println!("cheapest: {}", items[0].name);
let v = vec![1, 2, 3];
let owned: Vec<i32> = v.iter().copied().collect();
let idx: i32 = 1;
println!("{owned:?} {}", owned[idx as usize]);
}
Output:
Item { name: "sword", price: 12.5 } equal: true
1 | 2 | 3
a | b
[19.0, 21.5, 23.25]
cheapest: potion
[1, 2, 3] 2