{"id":"f22bdcc02942925a","repo":"rust-lang/rust","slug":"escaping-bound-vars-in","errorCode":null,"errorMessage":"escaping bound vars in {:?}","messagePattern":"escaping bound vars in (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"compiler/rustc_next_trait_solver/src/solve/mod.rs","lineNumber":275,"sourceCode":"            }\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    }\n}\n\n#[derive(Debug)]\nenum MergeCandidateInfo {\n    AlwaysApplicable(usize),\n    EqualResponse,\n}\n\nimpl<D, I> EvalCtxt<'_, D>","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/rust-lang/rust/blob/22057b88b091743bc0fd8d592a9264f0a6951403/compiler/rustc_next_trait_solver/src/solve/mod.rs#L257-L293","documentation":"A `panic!` in `compute_const_arg_has_type_goal` triggered when a const argument is a `ConstKind::Bound` — i.e. it references a late-bound variable (de Bruijn index) that has escaped the binder it was introduced in. The new solver only ever handles fully instantiated, closed terms; a bound var present here means a binder was dropped or skipped during substitution/instantiation. This is a compiler invariant, not valid user IR.","triggerScenarios":"Hit when a const bound variable (introduced by `for<'a>`/higher-ranked or by a late-bound const param) is not replaced with a fresh inference variable/placeholder before the const flows into a `const_arg_has_type` goal. Reproducible with higher-ranked const bounds or nested binders combined with the next solver.","commonSituations":"Nightly-only features mixing higher-ranked bounds with const generics, or a buggy macro that synthesizes `ty::Const` with leftover `Bound` kinds. Also appears after refactors of `instantiate_binder_with_infer` that forget to substitute a const binder.","solutions":["Confirm the const is fully instantiated before entering the solver: every binder over consts should pass through `instantiate_binder_with_infer` (or the placeholder equivalent under `-Znext-solver`).","Bisect nightlies to find the regression and report with a reduced test using `--edition=2021 -Znext-solver`.","Switch off the next solver to verify it is new-solver-specific."],"exampleFix":"// before — late-bound const var escapes its binder\nfor<const N: usize> || {}\n// after — keep the bound var under its binder, or instantiate it\nfn g<F: for<const N: usize> Fn() -> [(); N]>(_: F) {}\n","handlingStrategy":"validation","validationCode":"// Reject goals whose types or consts still contain escaping late-bound\n// vars before passing them to the solver.\nfn has_escaping_bvars(tcx: TyCtxt<'_>, t: impl Visit) -> bool {\n    struct EscapeCheck { has_escaping: bool }\n    // bound vars are escaping when their DebruijnIndex is > outermost.\n    // rustc exposes this via `tcx.fold_regions` / util::has_escaping_bound_vars.\n    t.has_escaping_bound_vars()\n}\nif has_escaping_bvars(tcx, goal) { return Err(\"goal has escaping bound vars\"); }","typeGuard":"// Narrow to a goal known to be free of escaping bound vars.\nfn is_closed_goal(tcx: TyCtxt<'_>, goal: &Goal<'_>) -> bool {\n    !goal.predicate.visit_with(&mut EscapingBoundVarDetector).has_found()\n}","tryCatchPattern":"use std::panic;\nlet r = panic::catch_unwind(panic::AssertUnwindSafe(|| solver.evaluate(goal)));\nmatch r {\n    Ok(v) => v,\n    Err(_) => Err(\"next solver rejected escaping bound vars; re-instantiate under a binder\"),\n}","preventionTips":["Instantiate / skim late-bound vars (`for<'a>`) before constructing a goal so nothing escapes its binder.","Avoid HRTBs nested inside associated-type projections; they frequently leave escaping vars.","Use `tcx.replace_escaping_bound_vars_uncached` to eliminate them at the call site.","Treat any goal built from a `Binder` as suspect until it is fully instantiated."],"tags":["rustc","trait-solver","const-generics","higher-ranked","compiler-internal","ice"],"analyzedSha":"22057b88b091743bc0fd8d592a9264f0a6951403","analyzedAt":"2026-08-03T08:09:25.915Z","schemaVersion":2}