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

  1. Update to the latest nightly (rustup update nightly).
  2. Disable -Znext-solver (remove the flag or -Znext-solver=no).
  3. File an ICE at https://github.com/rust-lang/rust/issues including the goal from the panic and a minimal reproducer.
  4. 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

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


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/0f1690c9fce58e99.json. Report an issue: GitHub.