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
- Report the limitation on the generic_const_exprs tracking issue, attaching the repro showing the non-rigid alias const.
- Avoid passing unevaluated/abstract associated consts as const arguments under -Znext-solver; materialize/evaluate them first.
- Disable -Znext-solver until non-rigid alias const typing is implemented.
- 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
- Always supply literal or fully-evaluated const expressions to generic const params — never an unevaluated `const { ... }` block or path.
- Split const-generic code into a separate crate compiled on stable, then depend on it from the next-solver crate.
- Avoid const generics whose type-checking requires the solver to evaluate the const at definition time.
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
- unexpected const kind: {:?}
- unexpected orig_value: {ct:?}
- ConstEquate should not be emitted when `-Znext-solver` is ac
- `feature(generic_const_exprs)` is not supported in the new t
- this never happens at the root, we're never in erased mode h
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/a4613b300ad0a96b.json.
Report an issue: GitHub.