rust-lang/rust · critical

DiscriminantKind is not const

Error message

DiscriminantKind is not const

What it means

Internal `unreachable!` in the next-gen trait solver's const-effect candidate assembly for `DiscriminantKind` (`core::marker::DiscriminantKind`), the trait backing `core::mem::discriminant`/`mem::Discriminant`. The trait is implemented for every type automatically by the compiler and has no const variant, so probing a const candidate is a routing bug. This ICEs the compiler.

Source

Thrown at compiler/rustc_next_trait_solver/src/solve/effect_goals.rs:413

    fn consider_builtin_async_iterator_candidate(
        _ecx: &mut EvalCtxt<'_, D>,
        _goal: Goal<I, Self>,
    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
        unreachable!("AsyncIterator is not const")
    }

    fn consider_builtin_coroutine_candidate(
        _ecx: &mut EvalCtxt<'_, D>,
        _goal: Goal<I, Self>,
    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
        unreachable!("Coroutine is not const")
    }

    fn consider_builtin_discriminant_kind_candidate(
        _ecx: &mut EvalCtxt<'_, D>,
        _goal: Goal<I, Self>,
    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
        unreachable!("DiscriminantKind is not const")
    }

    fn consider_builtin_destruct_candidate(
        ecx: &mut EvalCtxt<'_, D>,
        goal: Goal<I, Self>,
    ) -> Result<Candidate<I>, NoSolutionOrRerunNonErased> {
        let cx = ecx.cx();

        let self_ty = goal.predicate.self_ty();
        let const_conditions = structural_traits::const_conditions_for_destruct(cx, self_ty)?;

        ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
            ecx.add_goals(
                GoalSource::AliasBoundConstCondition,
                const_conditions.into_iter().map(|trait_ref| {
                    goal.with(
                        cx,
                        ty::Binder::dummy(trait_ref)

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Avoid requiring a const bound on `DiscriminantKind`; it is a compiler-implemented marker with no const impl.
  2. Move the `mem::discriminant`/`Discriminant` usage out of the `const fn` or const context.
  3. Report the ICE upstream with the minimal const-fn reproducer and `-Znext-solver` flags.
  4. Bisect nightlies — marker-trait const routing is actively being refined.

Example fix

// before
const fn tag<T: const DiscriminantKind>(t: &T) -> Discriminant<T> { discriminant(t) }

// after
fn tag<T>(t: &T) -> Discriminant<T> { discriminant(t) }
Defensive patterns

Strategy: validation

Validate before calling

// build.rs: reject const DiscriminantKind effect goals
fn main() {
    let src = std::fs::read_to_string("src/lib.rs").unwrap_or_default();
    for banned in ["~const DiscriminantKind", "const DiscriminantKind"] {
        assert!(!src.contains(banned), "rejected: {banned} — DiscriminantKind has no const builtin candidate");
    }
    println!("cargo:rerun-if-changed=src/lib.rs");
}

Prevention

When it happens

Trigger: The host-effect solver is asked to prove `T: const DiscriminantKind` (or `~const`) — typically via `mem::discriminant(&t)` or `Discriminant::<T>` referenced inside a `const fn` that propagates a const bound, or via a `#[const_trait]` whose implied bounds include `DiscriminantKind`.

Common situations: Calling `mem::discriminant` or pattern-matching with `Discriminant` inside nightly `const fn`; generic const code that auto-derives marker-trait bounds; `-Znext-solver` exposing previously-unhit effect-goal branches; nightly regression after auto-trait/marker const routing changes.

Related errors


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