Hide Binders internals more
This commit is contained in:
parent
6e9798a992
commit
69714d36e6
@ -702,7 +702,7 @@ impl_from!(Struct, Union, Enum for Adt);
|
||||
impl Adt {
|
||||
pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
|
||||
let subst = db.generic_defaults(self.into());
|
||||
subst.iter().any(|ty| ty.value.is_unknown())
|
||||
subst.iter().any(|ty| ty.skip_binders().is_unknown())
|
||||
}
|
||||
|
||||
/// Turns this ADT into a type. Any type parameters of the ADT will be
|
||||
@ -1089,7 +1089,7 @@ pub struct TypeAlias {
|
||||
impl TypeAlias {
|
||||
pub fn has_non_default_type_params(self, db: &dyn HirDatabase) -> bool {
|
||||
let subst = db.generic_defaults(self.id.into());
|
||||
subst.iter().any(|ty| ty.value.is_unknown())
|
||||
subst.iter().any(|ty| ty.skip_binders().is_unknown())
|
||||
}
|
||||
|
||||
pub fn module(self, db: &dyn HirDatabase) -> Module {
|
||||
|
@ -494,9 +494,9 @@ impl<'db> SemanticsImpl<'db> {
|
||||
fn resolve_method_call_as_callable(&self, call: &ast::MethodCallExpr) -> Option<Callable> {
|
||||
// FIXME: this erases Substs
|
||||
let func = self.resolve_method_call(call)?;
|
||||
let ty = self.db.value_ty(func.into());
|
||||
let (ty, _) = self.db.value_ty(func.into()).into_value_and_skipped_binders();
|
||||
let resolver = self.analyze(call.syntax()).resolver;
|
||||
let ty = Type::new_with_resolver(self.db, &resolver, ty.value)?;
|
||||
let ty = Type::new_with_resolver(self.db, &resolver, ty)?;
|
||||
let mut res = ty.as_callable(self.db)?;
|
||||
res.is_bound_method = true;
|
||||
Some(res)
|
||||
|
@ -245,7 +245,8 @@ impl<'a, 'b> ExprValidator<'a, 'b> {
|
||||
Some(callee) => callee,
|
||||
None => return,
|
||||
};
|
||||
let sig = db.callable_item_signature(callee.into()).value;
|
||||
let sig =
|
||||
db.callable_item_signature(callee.into()).into_value_and_skipped_binders().0;
|
||||
|
||||
(sig, args)
|
||||
}
|
||||
|
@ -353,7 +353,7 @@ impl HirDisplay for Ty {
|
||||
.as_ref()
|
||||
.map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
|
||||
let bounds = data.subst(parameters);
|
||||
bounds.value
|
||||
bounds.into_value_and_skipped_binders().0
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
@ -543,7 +543,7 @@ impl HirDisplay for Ty {
|
||||
.as_ref()
|
||||
.map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
|
||||
let bounds = data.subst(¶meters);
|
||||
write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
|
||||
write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?;
|
||||
// FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
|
||||
}
|
||||
ImplTraitId::AsyncBlockTypeImplTrait(..) => {
|
||||
@ -630,7 +630,7 @@ impl HirDisplay for Ty {
|
||||
.as_ref()
|
||||
.map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
|
||||
let bounds = data.subst(&opaque_ty.substitution);
|
||||
write_bounds_like_dyn_trait_with_prefix("impl", &bounds.value, f)?;
|
||||
write_bounds_like_dyn_trait_with_prefix("impl", bounds.skip_binders(), f)?;
|
||||
}
|
||||
ImplTraitId::AsyncBlockTypeImplTrait(..) => {
|
||||
write!(f, "{{async block}}")?;
|
||||
|
@ -118,49 +118,27 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
|
||||
}
|
||||
|
||||
impl<T> Binders<T> {
|
||||
pub fn new(num_binders: usize, value: T) -> Self {
|
||||
Self { num_binders, value }
|
||||
}
|
||||
|
||||
pub fn wrap_empty(value: T) -> Self
|
||||
where
|
||||
T: TypeWalk,
|
||||
{
|
||||
Self { num_binders: 0, value: value.shift_bound_vars(DebruijnIndex::ONE) }
|
||||
}
|
||||
|
||||
pub fn as_ref(&self) -> Binders<&T> {
|
||||
Binders { num_binders: self.num_binders, value: &self.value }
|
||||
}
|
||||
|
||||
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> {
|
||||
Binders { num_binders: self.num_binders, value: f(self.value) }
|
||||
}
|
||||
|
||||
pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> {
|
||||
Some(Binders { num_binders: self.num_binders, value: f(self.value)? })
|
||||
}
|
||||
|
||||
pub fn skip_binders(&self) -> &T {
|
||||
&self.value
|
||||
}
|
||||
|
||||
pub fn into_value_and_skipped_binders(self) -> (T, usize) {
|
||||
(self.value, self.num_binders)
|
||||
Binders::empty(&Interner, value.shift_bound_vars(DebruijnIndex::ONE))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Clone> Binders<&T> {
|
||||
pub fn cloned(&self) -> Binders<T> {
|
||||
Binders { num_binders: self.num_binders, value: self.value.clone() }
|
||||
let (value, binders) = self.into_value_and_skipped_binders();
|
||||
Binders::new(binders, value.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TypeWalk> Binders<T> {
|
||||
/// Substitutes all variables.
|
||||
pub fn subst(self, subst: &Substitution) -> T {
|
||||
assert_eq!(subst.len(&Interner), self.num_binders);
|
||||
self.value.subst_bound_vars(subst)
|
||||
let (value, binders) = self.into_value_and_skipped_binders();
|
||||
assert_eq!(subst.len(&Interner), binders);
|
||||
value.subst_bound_vars(subst)
|
||||
}
|
||||
}
|
||||
|
||||
@ -334,12 +312,12 @@ impl Ty {
|
||||
/// If this is a `dyn Trait` type, this returns the `Trait` part.
|
||||
fn dyn_trait_ref(&self) -> Option<&TraitRef> {
|
||||
match self.kind(&Interner) {
|
||||
TyKind::Dyn(dyn_ty) => {
|
||||
dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() {
|
||||
TyKind::Dyn(dyn_ty) => dyn_ty.bounds.skip_binders().interned().get(0).and_then(|b| {
|
||||
match b.skip_binders() {
|
||||
WhereClause::Implemented(trait_ref) => Some(trait_ref),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -459,7 +437,7 @@ impl Ty {
|
||||
ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(),
|
||||
};
|
||||
|
||||
predicates.map(|it| it.value)
|
||||
predicates.map(|it| it.into_value_and_skipped_binders().0)
|
||||
}
|
||||
TyKind::Placeholder(idx) => {
|
||||
let id = from_placeholder_idx(db, *idx);
|
||||
|
@ -832,12 +832,15 @@ pub fn associated_type_shorthand_candidates<R>(
|
||||
|
||||
match res {
|
||||
// FIXME: how to correctly handle higher-ranked bounds here?
|
||||
TypeNs::SelfType(impl_id) => {
|
||||
search(db.impl_trait(impl_id)?.value.shift_bound_vars_out(DebruijnIndex::ONE))
|
||||
}
|
||||
TypeNs::SelfType(impl_id) => search(
|
||||
db.impl_trait(impl_id)?
|
||||
.into_value_and_skipped_binders()
|
||||
.0
|
||||
.shift_bound_vars_out(DebruijnIndex::ONE),
|
||||
),
|
||||
TypeNs::GenericParam(param_id) => {
|
||||
let predicates = db.generic_predicates_for_param(param_id);
|
||||
let res = predicates.iter().find_map(|pred| match &pred.value.value {
|
||||
let res = predicates.iter().find_map(|pred| match pred.skip_binders().skip_binders() {
|
||||
// FIXME: how to correctly handle higher-ranked bounds here?
|
||||
WhereClause::Implemented(tr) => {
|
||||
search(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE))
|
||||
@ -1088,8 +1091,8 @@ fn fn_sig_for_struct_constructor(db: &dyn HirDatabase, def: StructId) -> PolyFnS
|
||||
let ctx =
|
||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
|
||||
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
|
||||
let ret = type_for_adt(db, def.into());
|
||||
Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
|
||||
let (ret, binders) = type_for_adt(db, def.into()).into_value_and_skipped_binders();
|
||||
Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
|
||||
}
|
||||
|
||||
/// Build the type of a tuple struct constructor.
|
||||
@ -1114,8 +1117,8 @@ fn fn_sig_for_enum_variant_constructor(db: &dyn HirDatabase, def: EnumVariantId)
|
||||
let ctx =
|
||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
|
||||
let params = fields.iter().map(|(_, field)| ctx.lower_ty(&field.type_ref)).collect::<Vec<_>>();
|
||||
let ret = type_for_adt(db, def.parent.into());
|
||||
Binders::new(ret.num_binders, CallableSig::from_params_and_return(params, ret.value, false))
|
||||
let (ret, binders) = type_for_adt(db, def.parent.into()).into_value_and_skipped_binders();
|
||||
Binders::new(binders, CallableSig::from_params_and_return(params, ret, false))
|
||||
}
|
||||
|
||||
/// Build the type of a tuple enum variant constructor.
|
||||
@ -1267,9 +1270,9 @@ pub(crate) fn impl_trait_query(db: &dyn HirDatabase, impl_id: ImplId) -> Option<
|
||||
let resolver = impl_id.resolver(db.upcast());
|
||||
let ctx =
|
||||
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
|
||||
let self_ty = db.impl_self_ty(impl_id);
|
||||
let (self_ty, binders) = db.impl_self_ty(impl_id).into_value_and_skipped_binders();
|
||||
let target_trait = impl_data.target_trait.as_ref()?;
|
||||
Some(Binders::new(self_ty.num_binders, ctx.lower_trait_ref(target_trait, Some(self_ty.value))?))
|
||||
Some(Binders::new(binders, ctx.lower_trait_ref(target_trait, Some(self_ty))?))
|
||||
}
|
||||
|
||||
pub(crate) fn return_type_impl_traits(
|
||||
|
@ -102,11 +102,11 @@ impl TraitImpls {
|
||||
for (_module_id, module_data) in crate_def_map.modules() {
|
||||
for impl_id in module_data.scope.impls() {
|
||||
let target_trait = match db.impl_trait(impl_id) {
|
||||
Some(tr) => tr.value.hir_trait_id(),
|
||||
Some(tr) => tr.skip_binders().hir_trait_id(),
|
||||
None => continue,
|
||||
};
|
||||
let self_ty = db.impl_self_ty(impl_id);
|
||||
let self_ty_fp = TyFingerprint::for_impl(&self_ty.value);
|
||||
let self_ty_fp = TyFingerprint::for_impl(self_ty.skip_binders());
|
||||
impls
|
||||
.map
|
||||
.entry(target_trait)
|
||||
@ -201,7 +201,7 @@ impl InherentImpls {
|
||||
}
|
||||
|
||||
let self_ty = db.impl_self_ty(impl_id);
|
||||
if let Some(fp) = TyFingerprint::for_impl(&self_ty.value) {
|
||||
if let Some(fp) = TyFingerprint::for_impl(self_ty.skip_binders()) {
|
||||
map.entry(fp).or_default().push(impl_id);
|
||||
}
|
||||
}
|
||||
@ -774,7 +774,7 @@ fn transform_receiver_ty(
|
||||
AssocContainerId::ModuleId(_) => unreachable!(),
|
||||
};
|
||||
let sig = db.callable_item_signature(function_id.into());
|
||||
Some(sig.value.params()[0].clone().subst_bound_vars(&substs))
|
||||
Some(sig.map(|s| s.params()[0].clone()).subst(&substs))
|
||||
}
|
||||
|
||||
pub fn implements_trait(
|
||||
|
@ -184,10 +184,15 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
|
||||
.db
|
||||
.return_type_impl_traits(func)
|
||||
.expect("impl trait id without impl traits");
|
||||
let data = &datas.value.impl_traits[idx as usize];
|
||||
let data = &datas.skip_binders().impl_traits[idx as usize];
|
||||
let bound = OpaqueTyDatumBound {
|
||||
bounds: make_binders(
|
||||
data.bounds.value.iter().cloned().map(|b| b.to_chalk(self.db)).collect(),
|
||||
data.bounds
|
||||
.skip_binders()
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|b| b.to_chalk(self.db))
|
||||
.collect(),
|
||||
1,
|
||||
),
|
||||
where_clauses: make_binders(vec![], 0),
|
||||
@ -535,7 +540,8 @@ fn impl_def_datum(
|
||||
.impl_trait(impl_id)
|
||||
// ImplIds for impls where the trait ref can't be resolved should never reach Chalk
|
||||
.expect("invalid impl passed to Chalk")
|
||||
.value;
|
||||
.into_value_and_skipped_binders()
|
||||
.0;
|
||||
let impl_data = db.impl_data(impl_id);
|
||||
|
||||
let generic_params = generics(db.upcast(), impl_id.into());
|
||||
@ -605,18 +611,22 @@ fn type_alias_associated_ty_value(
|
||||
_ => panic!("assoc ty value should be in impl"),
|
||||
};
|
||||
|
||||
let trait_ref = db.impl_trait(impl_id).expect("assoc ty value should not exist").value; // we don't return any assoc ty values if the impl'd trait can't be resolved
|
||||
let trait_ref = db
|
||||
.impl_trait(impl_id)
|
||||
.expect("assoc ty value should not exist")
|
||||
.into_value_and_skipped_binders()
|
||||
.0; // we don't return any assoc ty values if the impl'd trait can't be resolved
|
||||
|
||||
let assoc_ty = db
|
||||
.trait_data(trait_ref.hir_trait_id())
|
||||
.associated_type_by_name(&type_alias_data.name)
|
||||
.expect("assoc ty value should not exist"); // validated when building the impl data as well
|
||||
let ty = db.ty(type_alias.into());
|
||||
let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.value.to_chalk(db) };
|
||||
let (ty, binders) = db.ty(type_alias.into()).into_value_and_skipped_binders();
|
||||
let value_bound = rust_ir::AssociatedTyValueBound { ty: ty.to_chalk(db) };
|
||||
let value = rust_ir::AssociatedTyValue {
|
||||
impl_id: impl_id.to_chalk(db),
|
||||
associated_ty_id: to_assoc_type_id(assoc_ty),
|
||||
value: make_binders(value_bound, ty.num_binders),
|
||||
value: make_binders(value_bound, binders),
|
||||
};
|
||||
Arc::new(value)
|
||||
}
|
||||
@ -628,20 +638,15 @@ pub(crate) fn fn_def_datum_query(
|
||||
) -> Arc<FnDefDatum> {
|
||||
let callable_def: CallableDefId = from_chalk(db, fn_def_id);
|
||||
let generic_params = generics(db.upcast(), callable_def.into());
|
||||
let sig = db.callable_item_signature(callable_def);
|
||||
let (sig, binders) = db.callable_item_signature(callable_def).into_value_and_skipped_binders();
|
||||
let bound_vars = generic_params.bound_vars_subst(DebruijnIndex::INNERMOST);
|
||||
let where_clauses = convert_where_clauses(db, callable_def.into(), &bound_vars);
|
||||
let bound = rust_ir::FnDefDatumBound {
|
||||
// Note: Chalk doesn't actually use this information yet as far as I am aware, but we provide it anyway
|
||||
inputs_and_output: make_binders(
|
||||
rust_ir::FnDefInputsAndOutputDatum {
|
||||
argument_types: sig
|
||||
.value
|
||||
.params()
|
||||
.iter()
|
||||
.map(|ty| ty.clone().to_chalk(db))
|
||||
.collect(),
|
||||
return_type: sig.value.ret().clone().to_chalk(db),
|
||||
argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(db)).collect(),
|
||||
return_type: sig.ret().clone().to_chalk(db),
|
||||
}
|
||||
.shifted_in(&Interner),
|
||||
0,
|
||||
@ -650,12 +655,8 @@ pub(crate) fn fn_def_datum_query(
|
||||
};
|
||||
let datum = FnDefDatum {
|
||||
id: fn_def_id,
|
||||
sig: chalk_ir::FnSig {
|
||||
abi: (),
|
||||
safety: chalk_ir::Safety::Safe,
|
||||
variadic: sig.value.is_varargs,
|
||||
},
|
||||
binders: make_binders(bound, sig.num_binders),
|
||||
sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: sig.is_varargs },
|
||||
binders: make_binders(bound, binders),
|
||||
};
|
||||
Arc::new(datum)
|
||||
}
|
||||
|
@ -93,12 +93,13 @@ impl ToChalk for Ty {
|
||||
TyKind::BoundVar(idx) => chalk_ir::TyKind::BoundVar(idx).intern(&Interner),
|
||||
TyKind::InferenceVar(..) => panic!("uncanonicalized infer ty"),
|
||||
TyKind::Dyn(dyn_ty) => {
|
||||
let (bounds, binders) = dyn_ty.bounds.into_value_and_skipped_binders();
|
||||
let where_clauses = chalk_ir::QuantifiedWhereClauses::from_iter(
|
||||
&Interner,
|
||||
dyn_ty.bounds.value.interned().iter().cloned().map(|p| p.to_chalk(db)),
|
||||
bounds.interned().iter().cloned().map(|p| p.to_chalk(db)),
|
||||
);
|
||||
let bounded_ty = chalk_ir::DynTy {
|
||||
bounds: make_binders(where_clauses, 1),
|
||||
bounds: make_binders(where_clauses, binders),
|
||||
lifetime: LifetimeData::Static.intern(&Interner),
|
||||
};
|
||||
chalk_ir::TyKind::Dyn(bounded_ty).intern(&Interner)
|
||||
@ -486,13 +487,14 @@ where
|
||||
type Chalk = chalk_ir::Binders<T::Chalk>;
|
||||
|
||||
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Binders<T::Chalk> {
|
||||
let (value, binders) = self.into_value_and_skipped_binders();
|
||||
chalk_ir::Binders::new(
|
||||
chalk_ir::VariableKinds::from_iter(
|
||||
&Interner,
|
||||
std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
|
||||
.take(self.num_binders),
|
||||
.take(binders),
|
||||
),
|
||||
self.value.to_chalk(db),
|
||||
value.to_chalk(db),
|
||||
)
|
||||
}
|
||||
|
||||
@ -537,7 +539,8 @@ pub(super) fn generic_predicate_to_inline_bound(
|
||||
// An InlineBound is like a GenericPredicate, except the self type is left out.
|
||||
// We don't have a special type for this, but Chalk does.
|
||||
let self_ty_shifted_in = self_ty.clone().shift_bound_vars(DebruijnIndex::ONE);
|
||||
match &pred.value {
|
||||
let (pred, binders) = pred.as_ref().into_value_and_skipped_binders();
|
||||
match pred {
|
||||
WhereClause::Implemented(trait_ref) => {
|
||||
if trait_ref.self_type_parameter(&Interner) != &self_ty_shifted_in {
|
||||
// we can only convert predicates back to type bounds if they
|
||||
@ -549,7 +552,7 @@ pub(super) fn generic_predicate_to_inline_bound(
|
||||
.map(|ty| ty.clone().to_chalk(db).cast(&Interner))
|
||||
.collect();
|
||||
let trait_bound = rust_ir::TraitBound { trait_id: trait_ref.trait_id, args_no_self };
|
||||
Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), pred.num_binders))
|
||||
Some(make_binders(rust_ir::InlineBound::TraitBound(trait_bound), binders))
|
||||
}
|
||||
WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
|
||||
if projection_ty.self_type_parameter(&Interner) != &self_ty_shifted_in {
|
||||
@ -566,7 +569,7 @@ pub(super) fn generic_predicate_to_inline_bound(
|
||||
associated_ty_id: projection_ty.associated_ty_id,
|
||||
parameters: Vec::new(), // FIXME we don't support generic associated types yet
|
||||
};
|
||||
Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), pred.num_binders))
|
||||
Some(make_binders(rust_ir::InlineBound::AliasEqBound(alias_eq_bound), binders))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
|
@ -299,7 +299,41 @@ impl Substitution {
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
|
||||
pub struct Binders<T> {
|
||||
pub num_binders: usize,
|
||||
pub value: T,
|
||||
value: T,
|
||||
}
|
||||
|
||||
impl<T> Binders<T> {
|
||||
pub fn new(num_binders: usize, value: T) -> Self {
|
||||
Self { num_binders, value }
|
||||
}
|
||||
|
||||
pub fn empty(_interner: &Interner, value: T) -> Self {
|
||||
Self { num_binders: 0, value }
|
||||
}
|
||||
|
||||
pub fn as_ref(&self) -> Binders<&T> {
|
||||
Binders { num_binders: self.num_binders, value: &self.value }
|
||||
}
|
||||
|
||||
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> {
|
||||
Binders { num_binders: self.num_binders, value: f(self.value) }
|
||||
}
|
||||
|
||||
pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> {
|
||||
Some(Binders { num_binders: self.num_binders, value: f(self.value)? })
|
||||
}
|
||||
|
||||
pub fn skip_binders(&self) -> &T {
|
||||
&self.value
|
||||
}
|
||||
|
||||
pub fn into_value_and_skipped_binders(self) -> (T, usize) {
|
||||
(self.value, self.num_binders)
|
||||
}
|
||||
|
||||
pub fn skip_binders_mut(&mut self) -> &mut T {
|
||||
&mut self.value
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
|
||||
|
@ -139,7 +139,7 @@ impl TypeWalk for Ty {
|
||||
}
|
||||
}
|
||||
TyKind::Dyn(dyn_ty) => {
|
||||
for p in dyn_ty.bounds.value.interned().iter() {
|
||||
for p in dyn_ty.bounds.skip_binders().interned().iter() {
|
||||
p.walk(f);
|
||||
}
|
||||
}
|
||||
@ -167,7 +167,7 @@ impl TypeWalk for Ty {
|
||||
p_ty.substitution.walk_mut_binders(f, binders);
|
||||
}
|
||||
TyKind::Dyn(dyn_ty) => {
|
||||
for p in make_mut_slice(dyn_ty.bounds.value.interned_mut()) {
|
||||
for p in make_mut_slice(dyn_ty.bounds.skip_binders_mut().interned_mut()) {
|
||||
p.walk_mut_binders(f, binders.shifted_in());
|
||||
}
|
||||
}
|
||||
@ -294,7 +294,7 @@ impl TypeWalk for Substitution {
|
||||
|
||||
impl<T: TypeWalk> TypeWalk for Binders<T> {
|
||||
fn walk(&self, f: &mut impl FnMut(&Ty)) {
|
||||
self.value.walk(f);
|
||||
self.skip_binders().walk(f);
|
||||
}
|
||||
|
||||
fn walk_mut_binders(
|
||||
@ -302,7 +302,7 @@ impl<T: TypeWalk> TypeWalk for Binders<T> {
|
||||
f: &mut impl FnMut(&mut Ty, DebruijnIndex),
|
||||
binders: DebruijnIndex,
|
||||
) {
|
||||
self.value.walk_mut_binders(f, binders.shifted_in())
|
||||
self.skip_binders_mut().walk_mut_binders(f, binders.shifted_in())
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user