rust-lang/rust · error

non-rigid unevaluated constant for compute_const_arg_has_typ

Error message

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

What it means

compute_const_arg_has_type_goal handles rigid alias consts by reading their type directly, but a non-rigid (unevaluated, abstract) alias const has no computable type yet. The new solver has not implemented type-checking const arguments whose type depends on normalizing a non-rigid alias const, so it hits unimplemented! rather than risk an unsound answer.

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 22057b88b0)

Solutions

  1. Report the limitation on the generic_const_exprs tracking issue, attaching the repro showing the non-rigid alias const.
  2. Avoid passing unevaluated/abstract associated consts as const arguments under -Znext-solver; materialize/evaluate them first.
  3. Disable -Znext-solver until non-rigid alias const typing is implemented.
  4. Provide an explicit type annotation or const evaluation hint so the const resolves to a rigid/value form before the goal is checked.

Example fix

// before: non-rigid alias const used as a const arg whose type must be inferred
fn f<const N: usize>() {}
fn g<T: Trait<Assoc: usize>>() { f::<{ <T as Trait>::Assoc }>(); } // non-rigid alias

// after: force evaluation / use a concrete const
fn g<T: Trait>() { f::<{ <T as Trait>::ASSUMED }>(); } // supply a rigid/value const instead
Defensive patterns

Strategy: validation

Validate before calling

// `compute_const_arg_has_type_goal` requires the const arg to be rigid (evaluated).
// Validate every const generic arg is rigid before passing it in.
fn const_arg_is_rigid(ct: &ConstArg) -> bool {
    matches!(ct, ConstArg::Evaluated(_) | ConstArg::Param(_)) && !matches!(ct, ConstArg::Unevaluated(_))
}
fn assert_rigid<C>(c: &C) where C: AsRef<ConstArg> { assert!(const_arg_is_rigid(c.as_ref())); }

Type guard

trait Rigid { fn is_rigid(&self) -> bool; }
impl Rigid for ConstArg { fn is_rigid(&self) -> bool { !matches!(self, ConstArg::Unevaluated(_)) } }
fn use_rigid<C: Rigid>(c: C) -> C { assert!(c.is_rigid()); c }

Try / catch

use std::panic::{catch_unwind, AssertUnwindSafe};
let ok = catch_unwind(AssertUnwindSafe(|| compute_const_arg_has_type(ct)));
ok.unwrap_or_else(|_| Err(TypeError::UnevaluatedConst))

Prevention

When it happens

Trigger: Triggered when compute_const_arg_has_type_goal (compiler/rustc_next_trait_solver/src/solve/mod.rs:245) structurally normalizes a const and finds ConstKind::Alias(IsRigid::No, _) — an opaque/abstract alias const used as a const argument whose type must be checked.

Common situations: ICE/error when writing const-generic code that passes an unevaluated abstract const (e.g. from an associated const whose defining impl is not yet known) where its type also needs checking, under -Znext-solver. Closely related to the unfinished generic_const_exprs work.

Related errors


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