rust-lang/rust · critical
`Destruct` does not have an associated type: {:?}
Error message
`Destruct` does not have an associated type: {:?} What it means
consider_builtin_destruct_candidate (normalizes_to.rs:1040) panics unconditionally. The Destruct auto-trait (the destructor-presence analysis that replaced ad-hoc Drop checking) declares no associated types, so a NormalizesTo projection goal against Destruct is impossible. Trait goals for Destruct are handled by a real implementation in trait_goals.rs; reaching this normalizes_to.rs stub means the solver built a projection goal for an associated-type-less trait.
Source
Thrown at compiler/rustc_next_trait_solver/src/solve/normalizes_to.rs:1040
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
| ty::Alias(ty::IsRigid::No, _)
| ty::Bound(..) => panic!(
"unexpected self ty `{:?}` when normalizing `<T as DiscriminantKind>::Discriminant`",
goal.predicate.self_ty()
),
};
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
ecx.instantiate_normalizes_to_term(goal, discriminant_ty.into())?;
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
fn consider_builtin_destruct_candidate(
_ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
panic!("`Destruct` does not have an associated type: {:?}", goal);
}
fn consider_builtin_transmute_candidate(
_ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
panic!("`TransmuteFrom` does not have an associated type: {:?}", goal)
}
fn consider_builtin_bikeshed_guaranteed_no_drop_candidate(
_ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
unreachable!("`BikeshedGuaranteedNoDrop` does not have an associated type: {:?}", goal)
}
fn consider_builtin_field_candidate(
ecx: &mut EvalCtxt<'_, D>,View on GitHub (pinned to 22057b88b0)
Solutions
- Update to the latest nightly (rustup update nightly).
- Disable -Znext-solver (remove the flag or -Znext-solver=no).
- File an ICE at https://github.com/rust-lang/rust/issues including the goal from the panic and a minimal reproducer.
- Bisect nightlies to find the introducing commit.
Defensive patterns
Strategy: type-guard
Validate before calling
// `Destruct` (drop-check lang trait, nightly) is a marker with NO assoc types.
// Use only as a bound: `T: Destruct`. Never `<T as Destruct>::X`.
fn needs_destruct<T: core::ops::Destruct>() {} // OK
Type guard
trait _GuardDestruct<T: core::ops::Destruct> {} // bound-only sentinel
Prevention
- `Destruct` is nightly-only and a marker; never project off it.
- Gate nightly drop-check features behind `#[cfg(feature = "nightly")]`.
- Lint against `as Destruct)>::`.
When it happens
Trigger: A NormalizesTo goal whose trait_ref is the Destruct lang item is routed into the next-solver builtin-candidate assembly. Valid Rust cannot project an associated type off Destruct, so this is an internal goal-construction/routing bug.
Common situations: Nightly rustc regression in the next solver's Destruct handling (the Destruct trait is itself relatively new and under active change); fuzzing; not produced by ordinary drop/destructor code.
Related errors
- no such associated type in `AsyncFn*`: {:?}
- `Tuple` does not have an associated type: {:?}
- `FusedIterator` does not have an associated type: {:?}
- unexpected associated item `{:?}` for `{self_ty:?}`
- `Unsize` does not have an associated type: {:?}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/0f1690c9fce58e99.json.
Report an issue: GitHub.