rust-lang/rust · critical
unexpected associated item `{:?}` for `{self_ty:?}`
Error message
unexpected associated item `{:?}` for `{self_ty:?}` What it means
consider_builtin_coroutine_candidate (normalizes_to.rs:947) handles projections for the Coroutine trait, which has exactly two associated types: CoroutineReturn and CoroutineYield (checked via is_projection_lang_item). The else arm at line 947 panics if the projection's def_id is neither — an invariant that the only well-formed coroutine projections are those two. It can only fire if the lang-item set contains a third coroutine projection that this match was not updated to recognize.
Source
Thrown at compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs:947
return Err(NoSolution.into());
};
// `async`-desugared coroutines do not implement the coroutine trait
let cx = ecx.cx();
if !cx.is_general_coroutine(def_id) {
return Err(NoSolution.into());
}
let coroutine = args.as_coroutine();
let def_id = goal.predicate.alias.expect_projection_ty_def_id();
let term = if cx.is_projection_lang_item(def_id, SolverProjectionLangItem::CoroutineReturn)
{
coroutine.return_ty().into()
} else if cx.is_projection_lang_item(def_id, SolverProjectionLangItem::CoroutineYield) {
coroutine.yield_ty().into()
} else {
panic!("unexpected associated item `{:?}` for `{self_ty:?}`", def_id)
};
Self::probe_and_consider_implied_clause(
ecx,
CandidateSource::BuiltinImpl(BuiltinImplSource::Misc),
goal,
ty::ProjectionPredicate {
projection_term: ty::AliasTerm::new(
ecx.cx(),
goal.predicate.alias.kind,
[self_ty, coroutine.resume_ty()],
),
term,
}
.upcast(cx),
// Technically, we need to check that the coroutine type is Sized,
// but that's already proven by the coroutine being WF.
[],View on GitHub (pinned to 22057b88b0)
Solutions
- Update to the latest nightly (rustup update nightly).
- Disable -Znext-solver to fall back to the legacy solver.
- File an ICE with the def_id and self_ty from the panic and a minimal reproducer (preferably using std::ops::Coroutine).
- Avoid manually projecting coroutine associated types on the affected nightly; rely on generator/async desugaring instead.
Defensive patterns
Strategy: validation
Validate before calling
// Generic catch-all for an associated item that doesn't exist on Self.
// Validate the item exists in the trait defn BEFORE projection:
trait Repo { fn get(&self, k: &str) -> u32; } // only `get` exists
fn use_repo<R: Repo>(r: &R) { let _ = r.get("x"); } // OK
Type guard
// Compile-time check that the projected item name matches the trait declaration:
const _: fn() = || {
fn _check<R: Repo>(_: &R) {}
};
Prevention
- Cross-check every associated item name against the trait declaration before referencing it.
- Avoid wildcard `use trait::*` which hides which items you actually project.
- When implementing a foreign trait, copy item signatures verbatim from rustdoc.
When it happens
Trigger: A NormalizesTo goal for a Coroutine projection whose def_id is neither CoroutineReturn nor CoroutineYield reaches the builtin-coroutine candidate path, under -Znext-solver. Requires a rustc internal where a new coroutine associated item exists but this arm predates it, or goal construction produced a malformed projection.
Common situations: Using coroutines/generators (nightly `gen`, `coroutine` trait) on a bleeding-edge nightly with -Znext-solver; a toolchain regression during rustc coroutine-trait refactoring; not triggered by typical async/await (which uses the Future path, not Coroutine's own assoc types).
Related errors
- no such associated type in `AsyncFn*`: {:?}
- `Tuple` does not have an associated type: {:?}
- `FusedIterator` does not have an associated type: {:?}
- `Unsize` does not have an associated type: {:?}
- `Destruct` does not have an associated type: {:?}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/4a7e7f909edf3444.json.
Report an issue: GitHub.