| name | rust-errors-trait-bounds |
| description | Use when the user hits trait-related error codes E0277 / E0599 / E0220 / E0308 / E0282, gets "trait bound not satisfied", "method not found", needs a missing `use` for a trait, or wonders about the 1.84 next-generation trait solver. Prevents adding pointless bounds, missing the trait-import that brings a method into scope, and confusing inference failure with a real bound failure. Covers: E0277 trait bound not satisfied, E0599 method not found in scope, E0220 associated type not found, E0308 type mismatch (trait-related cases), E0282 type annotations needed; fix patterns (import the trait, add the bound to the generic, derive the missing trait, blanket-impl reasoning), the 1.84 opt-in next-gen trait solver and how it changes diagnostics. Keywords: E0277, E0599, E0220, E0308, E0282, "trait bound not satisfied", "method not found", "no method named", "the trait is not implemented", "associated type not found", "type annotations needed", "cannot infer type", "trait not in scope", "missing use", "new trait solver", "next-gen trait solver", "derive missing", "where clause", "trait bound error".
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires Rust 1.85+, edition 2024. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
Rust Trait Bound Errors
Diagnose and fix the five trait-related rustc error codes. The root cause is almost always one of four things: a missing trait import, a missing bound on a generic, a missing trait implementation, or an inference failure that only looks trait-related.
Quick Reference
| Code | Message shape | Most common cause | First fix to try |
|---|
| E0277 | the trait bound \T: Trait` is not satisfied` | Generic lacks the bound, or type never implements the trait | Add T: Trait to the generic, or #[derive(Trait)] on the type |
| E0599 | no method named \m` found for type `T`` | Trait that defines the method is not imported | use the::Trait; to bring the method into scope |
| E0220 | associated type \A` not found for `Trait`` | Wrong associated type name | Use the exact name the trait declares (e.g. Item, Output) |
| E0308 | mismatched types | Concrete vs dyn Trait, or impl Trait unification failure | Box the trait object, or align the two concrete types |
| E0282 | type annotations needed | Inference has no anchor type | Add a let x: T annotation or a turbofish ::<T>() |
ALWAYS read the full error block, not just the first line. Rustc prints the following trait bounds were not satisfied and a help: note listing the exact missing bound and the source crate. That detail names the fix.
Decision Tree: Which Trait Error Do I Have?
rustc rejects trait-related code
├── "no method named ..." ............................. E0599
│ ├── method exists on a trait? .................. add `use TheTrait;`
│ ├── typo in method name? ....................... fix spelling
│ ├── method takes `&mut self`, value is `&`? .... make the binding `mut` / take `&mut`
│ └── method behind a Cargo feature? ............. enable the feature in Cargo.toml
├── "the trait bound `T: Trait` is not satisfied" .... E0277
│ ├── `T` is a generic parameter? ................ add `T: Trait` (see decision tree below)
│ ├── `T` is a concrete type you own? ............ `#[derive(Trait)]` or hand-write `impl Trait for T`
│ ├── `T` is a foreign type? ..................... wrap it (newtype) or pick a type that impls it
│ └── impl exists but gated? ..................... enable the dependency feature that provides it
├── "associated type `A` not found" .................. E0220
│ └── use the exact associated-type name the trait declares
├── "mismatched types" with a trait in the text ...... E0308
│ ├── concrete value where `dyn Trait` expected? . `Box::new(value)` / `&value as &dyn Trait`
│ ├── two `impl Trait` returns disagree? ......... return one named type, or `Box<dyn Trait>`
│ └── otherwise align the concrete types
└── "type annotations needed" ........................ E0282
└── add `let x: T`, turbofish `::<T>()`, or fully-qualified syntax
Decision Tree: Missing where-clause vs Missing impl vs Missing import
When you see E0277, decide WHERE the fix belongs before touching code.
E0277: `T: SomeTrait` is not satisfied
│
├── Is `T` a generic type parameter (declared with `<T>`)?
│ │
│ ├── YES → the bound is MISSING from the signature.
│ │ Fix: add `T: SomeTrait` to the `<T>` list or a `where` clause.
│ │ Rust checks function bodies against the SIGNATURE only, so
│ │ every trait the body uses must be declared on the signature.
│ │
│ └── NO → `T` is a concrete type. The trait is genuinely UNIMPLEMENTED.
│ │
│ ├── You own `T` → `#[derive(SomeTrait)]` if derivable,
│ │ else hand-write `impl SomeTrait for T`.
│ │
│ └── `T` is foreign (std or another crate) →
│ orphan rule blocks a direct impl. Use a newtype
│ wrapper, or change `T` to a type that already impls it.
│
└── Does a `help:` note say "the trait `SomeTrait` is implemented for `U`"?
→ an impl EXISTS for a near-miss type. You passed the wrong type,
or need a conversion (`.into()`, `&x`, `x.as_ref()`).
NEVER add a bound to a generic before confirming the body actually requires it. If the body never calls a method from SomeTrait, the bound is noise. See references/anti-patterns.md.
E0277: Trait Bound Not Satisfied
the trait bound \i32: Foo` is not satisfied` means a type was used where a trait was required. Rust checks the called function's SIGNATURE only, so the signature must declare every requirement.
trait Foo {
fn bar(&self);
}
fn run<T>(foo: T) {
foo.bar();
}
fn run<T: Foo>(foo: T) {
foo.bar();
}
#[derive(Debug, Clone, PartialEq)]
struct Point { x: i32, y: i32 }
impl std::fmt::Display for Point {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "({}, {})", self.x, self.y)
}
}
For a foreign type you cannot impl directly (orphan rule), wrap it in a newtype. See references/examples.md.
E0599: Method Not Found in Scope
no method named \m` found for type `T` in the current scopemost often means the trait providingm` is not imported. A trait method is only callable when the trait is in scope.
use std::io::Write;
fn dump(out: &mut impl Write) -> std::io::Result<()> {
out.write_all(b"data")?;
out.flush()
}
Rustc's E0599 output frequently prints items from traits can only be used if the trait is in scope and lists the exact use path. Apply that path verbatim. Other E0599 causes: a misspelled method name, calling a &mut self method through a & binding, or a method gated behind a Cargo feature. See references/methods.md.
E0220: Associated Type Not Found
associated type \F` not found for `T1`` means you named an associated type the trait does not declare.
trait Container {
type Item;
}
fn first<C: Container<Item = i32>>(_c: C) {}
The same error fires inside a trait body when you reference Self::Baz without declaring type Baz;. Declare every associated type before referencing it.
E0308: Mismatched Types (Trait-Related Cases)
mismatched types is general, but trait-flavoured cases have specific fixes.
trait Shape { fn area(&self) -> f64; }
struct Circle; struct Square;
impl Shape for Circle { fn area(&self) -> f64 { 3.14 } }
impl Shape for Square { fn area(&self) -> f64 { 4.0 } }
let shapes: Vec<Box<dyn Shape>> = vec![Box::new(Circle), Box::new(Square)];
A function returning impl Trait must return exactly ONE concrete type on every path. Two different types on two branches raise E0308. Return Box<dyn Trait> when the types genuinely differ. See references/examples.md.
E0282: Type Annotations Needed
type annotations needed is an INFERENCE failure, not a bound failure. Inference found no unique type and needs an anchor.
let v: Vec<i32> = Vec::new();
let v = Vec::<i32>::new();
let squares = (1..5).map(|n| n * n).collect::<Vec<i32>>();
let chars: Vec<_> = "abc".chars().collect();
Distinguish E0282 from E0277: E0282 says "needs annotation" (no type chosen yet); E0277 says "bound not satisfied" (a type WAS chosen and fails a requirement). NEVER paper over a deeper design problem with a turbofish. See references/anti-patterns.md.
The 1.84 Next-Generation Trait Solver
The next-generation trait solver is a reimplementation of the component that checks trait bounds, normalization, and type equality. As of Rust 1.84.0 (January 2025), it is used ONLY for coherence checking of trait impls, and that use is the DEFAULT, not opt-in.
Deterministic facts:
- For coherence checking, the new solver is the DEFAULT in 1.84+. It is not behind a flag.
- For everything else (checking bounds in function bodies, method resolution), the OLD solver is still the default. The new solver can be opted into experimentally with
-Znext-solver on a nightly toolchain only. NEVER rely on -Znext-solver in stable or production builds.
- The new solver fixes mostly theoretical correctness issues. It may report a few new
conflicting implementations of trait ... errors that the old solver missed. The Rust team's Crater run found affected patterns to be very rare.
- It also proves non-overlap more precisely, so some previously rejected impls now compile.
- Impact on diagnostics: phrasing of trait errors can shift slightly under the new solver. The error CODES (E0277 etc.) and the fixes in this skill stay the same.
When a coherence error appears only after upgrading to 1.84+, treat it as a genuine overlap the old solver missed. Make the impls non-overlapping. Do not assume it is a compiler bug.
Cross-References
- [[rust-syntax-traits]] : declaring traits, impl blocks, blanket impls, the orphan rule
- [[rust-syntax-generics]] : generic parameters,
where clauses, bound placement
- [[rust-syntax-trait-objects]] :
dyn Trait, boxing, dyn-compatibility
- [[rust-agents-compile-fix]] : ordered workflow for resolving a cascade of compiler errors
Reference Files
references/methods.md : every error code with full message text, all fix variants, the new-solver flag detail
references/examples.md : complete compilable before/after programs for each error code
references/anti-patterns.md : the bound-spam, wrong-import, and turbofish-masking traps