Auto merge of #144677 - nnethercote:bound-const-handling, r=lcnr

Improve bound const handling

A few changes to make const handling more similar to type handling.

r? `@compiler-errors` -errors
This commit is contained in:
bors
2025-08-03 05:26:43 +00:00
23 changed files with 123 additions and 97 deletions

View File

@@ -187,7 +187,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
types: &mut |_bound_ty: ty::BoundTy| {
unreachable!("we only replace regions in nll_relate, not types")
},
consts: &mut |_bound_var: ty::BoundVar| {
consts: &mut |_bound_const: ty::BoundConst| {
unreachable!("we only replace regions in nll_relate, not consts")
},
};
@@ -226,7 +226,7 @@ impl<'a, 'b, 'tcx> NllTypeRelating<'a, 'b, 'tcx> {
types: &mut |_bound_ty: ty::BoundTy| {
unreachable!("we only replace regions in nll_relate, not types")
},
consts: &mut |_bound_var: ty::BoundVar| {
consts: &mut |_bound_const: ty::BoundConst| {
unreachable!("we only replace regions in nll_relate, not consts")
},
};

View File

@@ -2498,7 +2498,7 @@ fn param_env_with_gat_bounds<'tcx>(
ty::Const::new_bound(
tcx,
ty::INNERMOST,
ty::BoundVar::from_usize(bound_vars.len() - 1),
ty::BoundConst { var: ty::BoundVar::from_usize(bound_vars.len() - 1) },
)
.into()
}

View File

@@ -189,7 +189,7 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>(
}
ty::GenericArgKind::Const(ct) => {
if let ty::ConstKind::Bound(ty::INNERMOST, bv) = ct.kind() {
mapping.insert(bv, tcx.mk_param_from_def(param))
mapping.insert(bv.var, tcx.mk_param_from_def(param))
} else {
return None;
}
@@ -307,16 +307,16 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for MapAndCompressBoundVars<'tcx> {
return ct;
}
if let ty::ConstKind::Bound(binder, old_var) = ct.kind()
if let ty::ConstKind::Bound(binder, old_bound) = ct.kind()
&& self.binder == binder
{
let mapped = if let Some(mapped) = self.mapping.get(&old_var) {
let mapped = if let Some(mapped) = self.mapping.get(&old_bound.var) {
mapped.expect_const()
} else {
let var = ty::BoundVar::from_usize(self.still_bound_vars.len());
self.still_bound_vars.push(ty::BoundVariableKind::Const);
let mapped = ty::Const::new_bound(self.tcx, ty::INNERMOST, var);
self.mapping.insert(old_var, mapped.into());
let mapped = ty::Const::new_bound(self.tcx, ty::INNERMOST, ty::BoundConst { var });
self.mapping.insert(old_bound.var, mapped.into());
mapped
};

View File

@@ -1077,7 +1077,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GenericParamAndBoundVarCollector<'_, 't
ty::ConstKind::Param(param) => {
self.params.insert(param.index);
}
ty::ConstKind::Bound(db, ty::BoundVar { .. }) if db >= self.depth => {
ty::ConstKind::Bound(db, _) if db >= self.depth => {
let guar = self.cx.dcx().delayed_bug("unexpected escaping late-bound const var");
return ControlFlow::Break(guar);
}

View File

@@ -2107,9 +2107,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let name = tcx.item_name(param_def_id);
ty::Const::new_param(tcx, ty::ParamConst::new(index, name))
}
Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => {
ty::Const::new_bound(tcx, debruijn, ty::BoundVar::from_u32(index))
}
Some(rbv::ResolvedArg::LateBound(debruijn, index, _)) => ty::Const::new_bound(
tcx,
debruijn,
ty::BoundConst { var: ty::BoundVar::from_u32(index) },
),
Some(rbv::ResolvedArg::Error(guar)) => ty::Const::new_error(tcx, guar),
arg => bug!("unexpected bound var resolution for {:?}: {arg:?}", path_hir_id),
}

View File

@@ -752,7 +752,8 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
) -> Ty<'tcx> {
debug_assert!(!self.infcx.is_some_and(|infcx| ty_var != infcx.shallow_resolve(ty_var)));
let var = self.canonical_var(var_kind, ty_var.into());
Ty::new_bound(self.tcx, self.binder_index, var.into())
let bt = ty::BoundTy { var, kind: ty::BoundTyKind::Anon };
Ty::new_bound(self.tcx, self.binder_index, bt)
}
/// Given a type variable `const_var` of the given kind, first check
@@ -768,6 +769,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
!self.infcx.is_some_and(|infcx| ct_var != infcx.shallow_resolve_const(ct_var))
);
let var = self.canonical_var(var_kind, ct_var.into());
ty::Const::new_bound(self.tcx, self.binder_index, var)
let bc = ty::BoundConst { var };
ty::Const::new_bound(self.tcx, self.binder_index, bc)
}
}

View File

@@ -133,7 +133,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for CanonicalInstantiator<'tcx> {
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
match ct.kind() {
ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.current_index => {
self.var_values[bound_const.as_usize()].expect_const()
self.var_values[bound_const.var.as_usize()].expect_const()
}
_ => ct.super_fold_with(self),
}
@@ -217,7 +217,7 @@ fn highest_var_in_clauses<'tcx>(c: ty::Clauses<'tcx>) -> usize {
if let ty::ConstKind::Bound(debruijn, bound_const) = ct.kind()
&& debruijn == self.current_index
{
self.max_var = self.max_var.max(bound_const.as_usize());
self.max_var = self.max_var.max(bound_const.var.as_usize());
} else if ct.has_vars_bound_at_or_above(self.current_index) {
ct.super_visit_with(self);
}

View File

@@ -430,12 +430,12 @@ impl<'tcx> InferCtxt<'tcx> {
}
GenericArgKind::Lifetime(result_value) => {
// e.g., here `result_value` might be `'?1` in the example above...
if let ty::ReBound(debruijn, br) = result_value.kind() {
if let ty::ReBound(debruijn, b) = result_value.kind() {
// ... in which case we would set `canonical_vars[0]` to `Some('static)`.
// We only allow a `ty::INNERMOST` index in generic parameters.
assert_eq!(debruijn, ty::INNERMOST);
opt_values[br.var] = Some(*original_value);
opt_values[b.var] = Some(*original_value);
}
}
GenericArgKind::Const(result_value) => {
@@ -444,7 +444,7 @@ impl<'tcx> InferCtxt<'tcx> {
// We only allow a `ty::INNERMOST` index in generic parameters.
assert_eq!(debruijn, ty::INNERMOST);
opt_values[b] = Some(*original_value);
opt_values[b.var] = Some(*original_value);
}
}
}

View File

@@ -1265,8 +1265,8 @@ impl<'tcx> InferCtxt<'tcx> {
fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx> {
self.args[bt.var.index()].expect_ty()
}
fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx> {
self.args[bv.index()].expect_const()
fn replace_const(&mut self, bc: ty::BoundConst) -> ty::Const<'tcx> {
self.args[bc.var.index()].expect_const()
}
}
let delegate = ToFreshVars { args };

View File

@@ -45,10 +45,10 @@ impl<'tcx> InferCtxt<'tcx> {
ty::PlaceholderType { universe: next_universe, bound: bound_ty },
)
},
consts: &mut |bound_var: ty::BoundVar| {
consts: &mut |bound_const: ty::BoundConst| {
ty::Const::new_placeholder(
self.tcx,
ty::PlaceholderConst { universe: next_universe, bound: bound_var },
ty::PlaceholderConst { universe: next_universe, bound: bound_const },
)
},
};

View File

@@ -93,9 +93,9 @@ impl<'tcx> Const<'tcx> {
pub fn new_bound(
tcx: TyCtxt<'tcx>,
debruijn: ty::DebruijnIndex,
var: ty::BoundVar,
bound_const: ty::BoundConst,
) -> Const<'tcx> {
Const::new(tcx, ty::ConstKind::Bound(debruijn, var))
Const::new(tcx, ty::ConstKind::Bound(debruijn, bound_const))
}
#[inline]
@@ -168,12 +168,16 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
Const::new_var(tcx, vid)
}
fn new_bound(interner: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
Const::new_bound(interner, debruijn, var)
fn new_bound(
interner: TyCtxt<'tcx>,
debruijn: ty::DebruijnIndex,
bound_const: ty::BoundConst,
) -> Self {
Const::new_bound(interner, debruijn, bound_const)
}
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
Const::new_bound(tcx, debruijn, var)
Const::new_bound(tcx, debruijn, ty::BoundConst { var })
}
fn new_placeholder(tcx: TyCtxt<'tcx>, placeholder: ty::PlaceholderConst) -> Self {

View File

@@ -152,7 +152,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type PlaceholderConst = ty::PlaceholderConst;
type ParamConst = ty::ParamConst;
type BoundConst = ty::BoundVar;
type BoundConst = ty::BoundConst;
type ValueConst = ty::Value<'tcx>;
type ExprConst = ty::Expr<'tcx>;
type ValTree = ty::ValTree<'tcx>;

View File

@@ -3,7 +3,7 @@ use rustc_hir::def_id::DefId;
use rustc_type_ir::data_structures::DelayedMap;
use crate::ty::{
self, Binder, BoundTy, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
self, Binder, BoundConst, BoundTy, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
TypeVisitableExt,
};
@@ -60,7 +60,7 @@ where
pub trait BoundVarReplacerDelegate<'tcx> {
fn replace_region(&mut self, br: ty::BoundRegion) -> ty::Region<'tcx>;
fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx>;
fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx>;
fn replace_const(&mut self, bc: ty::BoundConst) -> ty::Const<'tcx>;
}
/// A simple delegate taking 3 mutable functions. The used functions must
@@ -69,7 +69,7 @@ pub trait BoundVarReplacerDelegate<'tcx> {
pub struct FnMutDelegate<'a, 'tcx> {
pub regions: &'a mut (dyn FnMut(ty::BoundRegion) -> ty::Region<'tcx> + 'a),
pub types: &'a mut (dyn FnMut(ty::BoundTy) -> Ty<'tcx> + 'a),
pub consts: &'a mut (dyn FnMut(ty::BoundVar) -> ty::Const<'tcx> + 'a),
pub consts: &'a mut (dyn FnMut(ty::BoundConst) -> ty::Const<'tcx> + 'a),
}
impl<'a, 'tcx> BoundVarReplacerDelegate<'tcx> for FnMutDelegate<'a, 'tcx> {
@@ -79,8 +79,8 @@ impl<'a, 'tcx> BoundVarReplacerDelegate<'tcx> for FnMutDelegate<'a, 'tcx> {
fn replace_ty(&mut self, bt: ty::BoundTy) -> Ty<'tcx> {
(self.types)(bt)
}
fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx> {
(self.consts)(bv)
fn replace_const(&mut self, bc: ty::BoundConst) -> ty::Const<'tcx> {
(self.consts)(bc)
}
}
@@ -300,7 +300,13 @@ impl<'tcx> TyCtxt<'tcx> {
ty::BoundTy { var: shift_bv(t.var), kind: t.kind },
)
},
consts: &mut |c| ty::Const::new_bound(self, ty::INNERMOST, shift_bv(c)),
consts: &mut |c| {
ty::Const::new_bound(
self,
ty::INNERMOST,
ty::BoundConst { var: shift_bv(c.var) },
)
},
},
)
}
@@ -343,12 +349,12 @@ impl<'tcx> TyCtxt<'tcx> {
.expect_ty();
Ty::new_bound(self.tcx, ty::INNERMOST, BoundTy { var, kind })
}
fn replace_const(&mut self, bv: ty::BoundVar) -> ty::Const<'tcx> {
let entry = self.map.entry(bv);
fn replace_const(&mut self, bc: ty::BoundConst) -> ty::Const<'tcx> {
let entry = self.map.entry(bc.var);
let index = entry.index();
let var = ty::BoundVar::from_usize(index);
let () = entry.or_insert_with(|| ty::BoundVariableKind::Const).expect_const();
ty::Const::new_bound(self.tcx, ty::INNERMOST, var)
ty::Const::new_bound(self.tcx, ty::INNERMOST, BoundConst { var })
}
}

View File

@@ -908,34 +908,43 @@ impl<'tcx> rustc_type_ir::inherent::PlaceholderLike<TyCtxt<'tcx>> for Placeholde
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable)]
#[derive(TyEncodable, TyDecodable)]
pub struct BoundConst<'tcx> {
pub struct BoundConst {
pub var: BoundVar,
pub ty: Ty<'tcx>,
}
pub type PlaceholderConst = Placeholder<BoundVar>;
impl<'tcx> rustc_type_ir::inherent::BoundVarLike<TyCtxt<'tcx>> for BoundConst {
fn var(self) -> BoundVar {
self.var
}
fn assert_eq(self, var: ty::BoundVariableKind) {
var.expect_const()
}
}
pub type PlaceholderConst = Placeholder<BoundConst>;
impl<'tcx> rustc_type_ir::inherent::PlaceholderLike<TyCtxt<'tcx>> for PlaceholderConst {
type Bound = BoundVar;
type Bound = BoundConst;
fn universe(self) -> UniverseIndex {
self.universe
}
fn var(self) -> BoundVar {
self.bound
self.bound.var
}
fn with_updated_universe(self, ui: UniverseIndex) -> Self {
Placeholder { universe: ui, ..self }
}
fn new(ui: UniverseIndex, bound: BoundVar) -> Self {
fn new(ui: UniverseIndex, bound: BoundConst) -> Self {
Placeholder { universe: ui, bound }
}
fn new_anon(ui: UniverseIndex, var: BoundVar) -> Self {
Placeholder { universe: ui, bound: var }
Placeholder { universe: ui, bound: BoundConst { var } }
}
}

View File

@@ -232,6 +232,7 @@ TrivialLiftImpls! {
crate::mir::Promoted,
crate::mir::interpret::AllocId,
crate::mir::interpret::Scalar,
crate::ty::ParamConst,
rustc_abi::ExternAbi,
rustc_abi::Size,
rustc_hir::Safety,
@@ -271,10 +272,6 @@ TrivialTypeTraversalImpls! {
crate::ty::AssocItem,
crate::ty::AssocKind,
crate::ty::BoundRegion,
crate::ty::BoundVar,
crate::ty::InferConst,
crate::ty::Placeholder<crate::ty::BoundRegion>,
crate::ty::Placeholder<ty::BoundVar>,
crate::ty::UserTypeAnnotationIndex,
crate::ty::ValTree<'tcx>,
crate::ty::abstract_const::NotConstEvaluatable,
@@ -302,9 +299,8 @@ TrivialTypeTraversalImpls! {
// interners).
TrivialTypeTraversalAndLiftImpls! {
// tidy-alphabetical-start
crate::ty::ParamConst,
crate::ty::ParamTy,
crate::ty::Placeholder<crate::ty::BoundTy>,
crate::ty::PlaceholderType,
crate::ty::instance::ReifyReason,
rustc_hir::def_id::DefId,
// tidy-alphabetical-end
@@ -673,30 +669,30 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
folder: &mut F,
) -> Result<Self, F::Error> {
let kind = match self.kind() {
ConstKind::Param(p) => ConstKind::Param(p.try_fold_with(folder)?),
ConstKind::Infer(i) => ConstKind::Infer(i.try_fold_with(folder)?),
ConstKind::Bound(d, b) => {
ConstKind::Bound(d.try_fold_with(folder)?, b.try_fold_with(folder)?)
}
ConstKind::Placeholder(p) => ConstKind::Placeholder(p.try_fold_with(folder)?),
ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.try_fold_with(folder)?),
ConstKind::Value(v) => ConstKind::Value(v.try_fold_with(folder)?),
ConstKind::Error(e) => ConstKind::Error(e.try_fold_with(folder)?),
ConstKind::Expr(e) => ConstKind::Expr(e.try_fold_with(folder)?),
ConstKind::Param(_)
| ConstKind::Infer(_)
| ConstKind::Bound(..)
| ConstKind::Placeholder(_)
| ConstKind::Error(_) => return Ok(self),
};
if kind != self.kind() { Ok(folder.cx().mk_ct_from_kind(kind)) } else { Ok(self) }
}
fn super_fold_with<F: TypeFolder<TyCtxt<'tcx>>>(self, folder: &mut F) -> Self {
let kind = match self.kind() {
ConstKind::Param(p) => ConstKind::Param(p.fold_with(folder)),
ConstKind::Infer(i) => ConstKind::Infer(i.fold_with(folder)),
ConstKind::Bound(d, b) => ConstKind::Bound(d.fold_with(folder), b.fold_with(folder)),
ConstKind::Placeholder(p) => ConstKind::Placeholder(p.fold_with(folder)),
ConstKind::Unevaluated(uv) => ConstKind::Unevaluated(uv.fold_with(folder)),
ConstKind::Value(v) => ConstKind::Value(v.fold_with(folder)),
ConstKind::Error(e) => ConstKind::Error(e.fold_with(folder)),
ConstKind::Expr(e) => ConstKind::Expr(e.fold_with(folder)),
ConstKind::Param(_)
| ConstKind::Infer(_)
| ConstKind::Bound(..)
| ConstKind::Placeholder(_)
| ConstKind::Error(_) => return self,
};
if kind != self.kind() { folder.cx().mk_ct_from_kind(kind) } else { self }
}
@@ -705,17 +701,15 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for ty::Const<'tcx> {
impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for ty::Const<'tcx> {
fn super_visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> V::Result {
match self.kind() {
ConstKind::Param(p) => p.visit_with(visitor),
ConstKind::Infer(i) => i.visit_with(visitor),
ConstKind::Bound(d, b) => {
try_visit!(d.visit_with(visitor));
b.visit_with(visitor)
}
ConstKind::Placeholder(p) => p.visit_with(visitor),
ConstKind::Unevaluated(uv) => uv.visit_with(visitor),
ConstKind::Value(v) => v.visit_with(visitor),
ConstKind::Error(e) => e.visit_with(visitor),
ConstKind::Expr(e) => e.visit_with(visitor),
ConstKind::Error(e) => e.visit_with(visitor),
ConstKind::Param(_)
| ConstKind::Infer(_)
| ConstKind::Bound(..)
| ConstKind::Placeholder(_) => V::Result::output(),
}
}
}

View File

@@ -403,12 +403,6 @@ pub enum BoundTyKind {
Param(DefId),
}
impl From<BoundVar> for BoundTy {
fn from(var: BoundVar) -> Self {
BoundTy { var, kind: BoundTyKind::Anon }
}
}
/// Constructors for `Ty`
impl<'tcx> Ty<'tcx> {
/// Avoid using this in favour of more specific `new_*` methods, where possible.

View File

@@ -789,10 +789,10 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
},
GenericArgKind::Lifetime(r) => match r.kind() {
ty::ReBound(debruijn, br) => {
ty::ReBound(debruijn, b) => {
// We only allow a `ty::INNERMOST` index in generic parameters.
assert_eq!(debruijn, ty::INNERMOST);
cvar == br.var
cvar == b.var
}
_ => false,
},
@@ -801,7 +801,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
ty::ConstKind::Bound(debruijn, b) => {
// We only allow a `ty::INNERMOST` index in generic parameters.
assert_eq!(debruijn, ty::INNERMOST);
cvar == b
cvar == b.var
}
_ => false,
},

View File

@@ -548,7 +548,10 @@ fn plug_infer_with_placeholders<'tcx>(
ct,
ty::Const::new_placeholder(
self.infcx.tcx,
ty::Placeholder { universe: self.universe, bound: self.next_var() },
ty::Placeholder {
universe: self.universe,
bound: ty::BoundConst { var: self.next_var() },
},
),
)
else {

View File

@@ -706,7 +706,10 @@ fn replace_param_and_infer_args_with_placeholder<'tcx>(
self.idx += 1;
ty::Const::new_placeholder(
self.tcx,
ty::PlaceholderConst { universe: ty::UniverseIndex::ROOT, bound: idx },
ty::PlaceholderConst {
universe: ty::UniverseIndex::ROOT,
bound: ty::BoundConst { var: idx },
},
)
} else {
c.super_fold_with(self)

View File

@@ -222,7 +222,7 @@ pub struct PlaceholderReplacer<'a, 'tcx> {
infcx: &'a InferCtxt<'tcx>,
mapped_regions: FxIndexMap<ty::PlaceholderRegion, ty::BoundRegion>,
mapped_types: FxIndexMap<ty::PlaceholderType, ty::BoundTy>,
mapped_consts: FxIndexMap<ty::PlaceholderConst, ty::BoundVar>,
mapped_consts: FxIndexMap<ty::PlaceholderConst, ty::BoundConst>,
universe_indices: &'a [Option<ty::UniverseIndex>],
current_index: ty::DebruijnIndex,
}
@@ -232,7 +232,7 @@ impl<'a, 'tcx> PlaceholderReplacer<'a, 'tcx> {
infcx: &'a InferCtxt<'tcx>,
mapped_regions: FxIndexMap<ty::PlaceholderRegion, ty::BoundRegion>,
mapped_types: FxIndexMap<ty::PlaceholderType, ty::BoundTy>,
mapped_consts: FxIndexMap<ty::PlaceholderConst, ty::BoundVar>,
mapped_consts: FxIndexMap<ty::PlaceholderConst, ty::BoundConst>,
universe_indices: &'a [Option<ty::UniverseIndex>],
value: T,
) -> T {

View File

@@ -274,8 +274,9 @@ impl<I: Interner, T: IntoIterator> Binder<I, T> {
pub struct ValidateBoundVars<I: Interner> {
bound_vars: I::BoundVarKinds,
binder_index: ty::DebruijnIndex,
// We may encounter the same variable at different levels of binding, so
// this can't just be `Ty`
// We only cache types because any complex const will have to step through
// a type at some point anyways. We may encounter the same variable at
// different levels of binding, so this can't just be `Ty`.
visited: SsoHashSet<(ty::DebruijnIndex, I::Ty)>,
}
@@ -319,6 +320,24 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
t.super_visit_with(self)
}
fn visit_const(&mut self, c: I::Const) -> Self::Result {
if c.outer_exclusive_binder() < self.binder_index {
return ControlFlow::Break(());
}
match c.kind() {
ty::ConstKind::Bound(debruijn, bound_const) if debruijn == self.binder_index => {
let idx = bound_const.var().as_usize();
if self.bound_vars.len() <= idx {
panic!("Not enough bound vars: {:?} not found in {:?}", c, self.bound_vars);
}
bound_const.assert_eq(self.bound_vars.get(idx).unwrap());
}
_ => {}
};
c.super_visit_with(self)
}
fn visit_region(&mut self, r: I::Region) -> Self::Result {
match r.kind() {
ty::ReBound(index, br) if index == self.binder_index => {

View File

@@ -251,7 +251,7 @@ pub trait Const<I: Interner<Const = Self>>:
fn new_var(interner: I, var: ty::ConstVid) -> Self;
fn new_bound(interner: I, debruijn: ty::DebruijnIndex, var: I::BoundConst) -> Self;
fn new_bound(interner: I, debruijn: ty::DebruijnIndex, bound_const: I::BoundConst) -> Self;
fn new_anon_bound(interner: I, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self;

View File

@@ -387,16 +387,6 @@ rustc_index::newtype_index! {
pub struct BoundVar {}
}
impl<I: Interner> inherent::BoundVarLike<I> for BoundVar {
fn var(self) -> BoundVar {
self
}
fn assert_eq(self, _var: I::BoundVarKind) {
unreachable!("FIXME: We really should have a separate `BoundConst` for consts")
}
}
/// Represents the various closure traits in the language. This
/// will determine the type of the environment (`self`, in the
/// desugaring) argument that the closure expects.