{"id":"a4613b300ad0a96b","repo":"rust-lang/rust","slug":"non-rigid-unevaluated-constant-for-compute-const-a","errorCode":null,"errorMessage":"non-rigid unevaluated constant for compute_const_arg_has_type_goal: {ct:?}","messagePattern":"non-rigid unevaluated constant for compute_const_arg_has_type_goal: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"compiler/rustc_next_trait_solver/src/solve/mod.rs","lineNumber":266,"sourceCode":"    ) -> QueryResultOrRerunNonErased<I> {\n        let (ct, ty) = goal.predicate;\n        let ct = self.structurally_normalize_const(goal.param_env, ct)?;\n\n        let ct_ty = match ct.kind() {\n            ty::ConstKind::Infer(_) => {\n                return self\n                    .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)\n                    .map_err(Into::into);\n            }\n            ty::ConstKind::Error(_) => {\n                return self\n                    .evaluate_added_goals_and_make_canonical_response(Certainty::Yes)\n                    .map_err(Into::into);\n            }\n            ty::ConstKind::Alias(ty::IsRigid::Yes, alias_const) => {\n                alias_const.type_of(self.cx()).skip_norm_wip()\n            }\n            ty::ConstKind::Alias(ty::IsRigid::No, _) => unimplemented!(\n                \"non-rigid unevaluated constant for compute_const_arg_has_type_goal: {ct:?}\"\n            ),\n            ty::ConstKind::Expr(_) => unimplemented!(\n                \"`feature(generic_const_exprs)` is not supported in the new trait solver\"\n            ),\n            ty::ConstKind::Param(_) => {\n                unreachable!(\"`ConstKind::Param` should have been canonicalized to `Placeholder`\")\n            }\n            ty::ConstKind::Bound(_, _) => panic!(\"escaping bound vars in {:?}\", ct),\n            ty::ConstKind::Value(cv) => cv.ty(),\n            ty::ConstKind::Placeholder(placeholder) => {\n                placeholder.find_const_ty_from_env(goal.param_env)\n            }\n        };\n\n        self.eq(goal.param_env, ct_ty, ty)?;\n        self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes).map_err(Into::into)\n    }","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_next_trait_solver/src/solve/mod.rs#L248-L284","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: non-rigid alias const used as a const arg whose type must be inferred\nfn f<const N: usize>() {}\nfn g<T: Trait<Assoc: usize>>() { f::<{ <T as Trait>::Assoc }>(); } // non-rigid alias\n\n// after: force evaluation / use a concrete const\nfn g<T: Trait>() { f::<{ <T as Trait>::ASSUMED }>(); } // supply a rigid/value const instead","handlingStrategy":"validation","validationCode":"// `compute_const_arg_has_type_goal` requires the const arg to be rigid (evaluated).\n// Validate every const generic arg is rigid before passing it in.\nfn const_arg_is_rigid(ct: &ConstArg) -> bool {\n    matches!(ct, ConstArg::Evaluated(_) | ConstArg::Param(_)) && !matches!(ct, ConstArg::Unevaluated(_))\n}\nfn assert_rigid<C>(c: &C) where C: AsRef<ConstArg> { assert!(const_arg_is_rigid(c.as_ref())); }","typeGuard":"trait Rigid { fn is_rigid(&self) -> bool; }\nimpl Rigid for ConstArg { fn is_rigid(&self) -> bool { !matches!(self, ConstArg::Unevaluated(_)) } }\nfn use_rigid<C: Rigid>(c: C) -> C { assert!(c.is_rigid()); c }","tryCatchPattern":"use std::panic::{catch_unwind, AssertUnwindSafe};\nlet ok = catch_unwind(AssertUnwindSafe(|| compute_const_arg_has_type(ct)));\nok.unwrap_or_else(|_| Err(TypeError::UnevaluatedConst))","preventionTips":["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."],"tags":["rust","rustc","trait-solver","ice","next-solver","const-generics","generic-const-exprs","alias-types"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}