rust-lang/rust · error

non-rigid unevaluated constant for…

Error message

non-rigid unevaluated constant for compute_const_arg_has_type_goal: {ct:?}

What it means

An `unimplemented!("non-rigid unevaluated constant for compute_const_arg_has_type_goal: {ct:?}")` ICE in the next trait solver. When the solver checks that a const argument has a given type, it handles rigid (fully normalized) alias constants but not non-rigid unevaluated alias constants — those require normalization the new solver cannot yet perform here, so it panics at mod.rs:266.

Solutions

  1. Do not enable `-Znext-solver` for crates using complex unevaluated const generics.
  2. Evaluate the const at the call site (use a concrete const value, not an alias, so it is rigid).
  3. Track upstream next-solver work on non-rigid const normalization.

Example fix

// before (next solver + non-rigid alias const -> ICE)
const N: usize = some_assoc_const::<T>();
let a: [u8; N];

// after — concrete const, rigid, or drop -Znext-solver
const N: usize = 16;
let a: [u8; N];
Defensive patterns

Strategy: fallback

Validate before calling

# Detect next-solver + unevaluated alias const generics
if [[ "${RUSTFLAGS:-}" == *next-solver* ]]; then
  rg -nE 'const [A-Z_0-9]+: .* =' src/ | rg -v '\b(digit|literal|concrete)\b'
  echo "avoid: non-rigid alias const args unsupported by next-solver"
fi

Prevention

When it happens

Trigger: Enabling `-Znext-solver` with code whose const arguments contain non-rigid unevaluated alias constants — e.g. generic const generics that have not been normalized/evaluated, often seen with `generic_const_exprs`-style or associated-const code.

Common situations: Nightly + `-Znext-solver` + const generics that rely on associated consts or unevaluated generic const expressions passed as type/array parameters.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/a4613b300ad0a96b. Report an issue: GitHub.

Appendix: source

Thrown at compiler/rustc_next_trait_solver/src/solve/mod.rs:266

    ) -> QueryResultOrRerunNonErased<I> {
        let (ct, ty) = goal.predicate;
        let ct = self.structurally_normalize_const(goal.param_env, ct)?;

        let ct_ty = match ct.kind() {
            ty::ConstKind::Infer(_) => {
                return self
                    .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
                    .map_err(Into::into);
            }
            ty::ConstKind::Error(_) => {
                return self
                    .evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
                    .map_err(Into::into);
            }
            ty::ConstKind::Alias(ty::IsRigid::Yes, alias_const) => {
                alias_const.type_of(self.cx()).skip_norm_wip()
            }
            ty::ConstKind::Alias(ty::IsRigid::No, _) => unimplemented!(
                "non-rigid unevaluated constant for compute_const_arg_has_type_goal: {ct:?}"
            ),
            ty::ConstKind::Expr(_) => unimplemented!(
                "`feature(generic_const_exprs)` is not supported in the new trait solver"
            ),
            ty::ConstKind::Param(_) => {
                unreachable!("`ConstKind::Param` should have been canonicalized to `Placeholder`")
            }
            ty::ConstKind::Bound(_, _) => panic!("escaping bound vars in {:?}", ct),
            ty::ConstKind::Value(cv) => cv.ty(),
            ty::ConstKind::Placeholder(placeholder) => {
                placeholder.find_const_ty_from_env(goal.param_env)
            }
        };

        self.eq(goal.param_env, ct_ty, ty)?;
        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes).map_err(Into::into)
    }

View on GitHub (pinned to 7088e4b63a)