rust-lang/rust · critical
unexpected orig_value: {ct:?}
Error message
unexpected orig_value: {ct:?} What it means
Const-typed counterpart of the orig_value invariant in EvalCtxt::build_stalled_on. When categorizing stalled const generic args, the only legal ConstKinds are Infer (stalls), and Param/Placeholder (no-op). Any other ConstKind (Value, Alias, Error, Bound, Expr) reaching this point means an unexpected const survived into the stalled-variable set, breaking the assumption that stalled consts are inference variables.
Source
Thrown at compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:871
) -> GoalStalledOn<I> {
// Remove the canonicalized universal vars, since we only care about stalled existentials.
let mut sub_roots = ThinVec::new();
stalled_vars.retain(|arg| match arg.kind() {
// Lifetimes can never stall goals.
ty::GenericArgKind::Lifetime(_) => false,
ty::GenericArgKind::Type(ty) => match ty.kind() {
ty::Infer(ty::TyVar(vid)) => {
sub_roots.push(self.delegate.sub_unification_table_root_var(vid));
true
}
ty::Infer(_) => true,
ty::Param(_) | ty::Placeholder(_) => false,
_ => unreachable!("unexpected orig_value: {ty:?}"),
},
ty::GenericArgKind::Const(ct) => match ct.kind() {
ty::ConstKind::Infer(_) => true,
ty::ConstKind::Param(_) | ty::ConstKind::Placeholder(_) => false,
_ => unreachable!("unexpected orig_value: {ct:?}"),
},
});
GoalStalledOn {
stalled_vars,
sub_roots,
stalled_certainty: certainty,
opaques: GoalStalledOnOpaques::Yes {
num_opaques_in_storage: canonical_goal
.canonical
.value
.predefined_opaques_in_body
.len(),
previously_succeeded_in_erased,
},
}
}
View on GitHub (pinned to 22057b88b0)
Solutions
- Report the ICE with the {ct:?} const printed by the panic message.
- Reduce the test case to a minimal const-generic example and attach it to the rustc issue.
- Disable -Znext-solver to unblock the build.
- If developing the solver, check that const orig_values are normalized/evaluated before stalled-vars are computed so only Infer consts remain.
Defensive patterns
Strategy: type-guard
Validate before calling
// Reject unevaluated/bare const values before they reach the solver.
fn const_arg_is_evaluable(ct: &ConstExpr) -> bool {
matches!(ct, ConstExpr::Lit(_) | ConstExpr::Path(_))
}
// use in a build.rs / lint pass over generic arguments Type guard
trait RigidConstArg { fn is_rigid(&self) -> bool; }
impl RigidConstArg for ConstValue {
fn is_rigid(&self) -> bool { !matches!(self.kind, ConstKind::Unevaluated(_) | ConstKind::Infer(_)) }
} Try / catch
use std::panic::{catch_unwind, AssertUnwindSafe};
let v = catch_unwind(AssertUnwindSafe(|| compute_const(ct)));
v.unwrap_or_else(|_| ConstValue::zero_sized_fallback()) Prevention
- Materialize every const generic argument to a concrete value at the call site — never pass an unevaluated const expression.
- Avoid `const` generics whose value depends on another generic parameter (the classic `orig_value` mismatch source).
- Add a unit test that builds the crate with `-Zminimal-versions` to catch const-shape regressions.
When it happens
Trigger: Hit when build_stalled_on in compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs:868 processes a GenericArgKind::Const whose kind is not Infer/Param/Placeholder — e.g. an unevaluated Alias const or a Value const improperly retained in stalled_vars.
Common situations: ICE triggered while solving const-dependent goals (array lengths, const generics) under -Znext-solver. Usually a compiler regression in const handling or canonicalization rather than a user-code defect.
Related errors
- unexpected orig_value: {ty:?}
- ConstEquate should not be emitted when `-Znext-solver` is ac
- Params should have been canonicalized to placeholders
- unexpected const kind: {:?}
- non-rigid unevaluated constant for compute_const_arg_has_typ
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/b1cd1c3895102aa2.json.
Report an issue: GitHub.