pub struct TyLoweringContext<'a> {
pub db: &'a dyn HirDatabase,
pub resolver: &'a Resolver,
+ in_binders: DebruijnIndex,
/// Note: Conceptually, it's thinkable that we could be in a location where
/// some type params should be represented as placeholders, and others
/// should be converted to variables. I think in practice, this isn't
let impl_trait_counter = std::cell::Cell::new(0);
let impl_trait_mode = ImplTraitLoweringMode::Disallowed;
let type_param_mode = TypeParamLoweringMode::Placeholder;
- Self { db, resolver, impl_trait_mode, impl_trait_counter, type_param_mode }
+ let in_binders = DebruijnIndex::INNERMOST;
+ Self { db, resolver, in_binders, impl_trait_mode, impl_trait_counter, type_param_mode }
+ }
+
+ pub fn with_shifted_in<T>(
+ &self,
+ debruijn: DebruijnIndex,
+ f: impl FnOnce(&TyLoweringContext) -> T,
+ ) -> T {
+ let new_ctx = Self {
+ in_binders: self.in_binders.shifted_in_from(debruijn),
+ impl_trait_counter: std::cell::Cell::new(self.impl_trait_counter.get()),
+ ..*self
+ };
+ let result = f(&new_ctx);
+ self.impl_trait_counter.set(new_ctx.impl_trait_counter.get());
+ result
+ }
+
+ pub fn shifted_in(self, debruijn: DebruijnIndex) -> Self {
+ Self { in_binders: self.in_binders.shifted_in_from(debruijn), ..self }
}
pub fn with_impl_trait_mode(self, impl_trait_mode: ImplTraitLoweringMode) -> Self {
}
TypeRef::DynTrait(bounds) => {
let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
- let predicates = bounds
- .iter()
- .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone()))
- .collect();
+ let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| {
+ bounds
+ .iter()
+ .flat_map(|b| GenericPredicate::from_type_bound(ctx, b, self_ty.clone()))
+ .collect()
+ });
Ty::Dyn(predicates)
}
TypeRef::ImplTrait(bounds) => {
match ctx.impl_trait_mode {
ImplTraitLoweringMode::Opaque => {
let self_ty = Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, 0));
- let predicates = bounds
- .iter()
- .flat_map(|b| {
- GenericPredicate::from_type_bound(ctx, b, self_ty.clone())
- })
- .collect();
+ let predicates = ctx.with_shifted_in(DebruijnIndex::ONE, |ctx| {
+ bounds
+ .iter()
+ .flat_map(|b| {
+ GenericPredicate::from_type_bound(ctx, b, self_ty.clone())
+ })
+ .collect()
+ });
Ty::Opaque(predicates)
}
ImplTraitLoweringMode::Param => {
(0, 0, 0, 0)
};
Ty::Bound(BoundVar::new(
- DebruijnIndex::INNERMOST,
+ ctx.in_binders,
idx as usize + parent_params + self_params + list_params,
))
}
TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id),
TypeParamLoweringMode::Variable => {
let idx = generics.param_idx(param_id).expect("matching generics");
- Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, idx))
+ Ty::Bound(BoundVar::new(ctx.in_binders, idx))
}
}
}
TypeParamLoweringMode::Placeholder => {
Substs::type_params_for_generics(&generics)
}
- TypeParamLoweringMode::Variable => Substs::bound_vars(&generics),
+ TypeParamLoweringMode::Variable => {
+ Substs::bound_vars(&generics, ctx.in_binders)
+ }
};
ctx.db.impl_self_ty(impl_id).subst(&substs)
}
TypeParamLoweringMode::Placeholder => {
Substs::type_params_for_generics(&generics)
}
- TypeParamLoweringMode::Variable => Substs::bound_vars(&generics),
+ TypeParamLoweringMode::Variable => {
+ Substs::bound_vars(&generics, ctx.in_binders)
+ }
};
ctx.db.ty(adt.into()).subst(&substs)
}
/// function body.
fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> Binders<Ty> {
let generics = generics(db.upcast(), def.into());
- let substs = Substs::bound_vars(&generics);
+ let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs))
}
return type_for_adt(db, def.into());
}
let generics = generics(db.upcast(), def.into());
- let substs = Substs::bound_vars(&generics);
+ let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs))
}
return type_for_adt(db, def.parent.into());
}
let generics = generics(db.upcast(), def.parent.into());
- let substs = Substs::bound_vars(&generics);
+ let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
Binders::new(substs.len(), Ty::apply(TypeCtor::FnDef(def.into()), substs))
}
fn type_for_adt(db: &dyn HirDatabase, adt: AdtId) -> Binders<Ty> {
let generics = generics(db.upcast(), adt.into());
- let substs = Substs::bound_vars(&generics);
+ let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
Binders::new(substs.len(), Ty::apply(TypeCtor::Adt(adt), substs))
}
let ctx =
TyLoweringContext::new(db, &resolver).with_type_param_mode(TypeParamLoweringMode::Variable);
let type_ref = &db.type_alias_data(t).type_ref;
- let substs = Substs::bound_vars(&generics);
+ let substs = Substs::bound_vars(&generics, DebruijnIndex::INNERMOST);
let inner = Ty::from_hir(&ctx, type_ref.as_ref().unwrap_or(&TypeRef::Error));
Binders::new(substs.len(), inner)
}
use super::{builtin, AssocTyValue, Canonical, ChalkContext, Impl, Obligation};
use crate::{
db::HirDatabase, display::HirDisplay, method_resolution::TyFingerprint, utils::generics,
- ApplicationTy, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
+ ApplicationTy, DebruijnIndex, GenericPredicate, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
};
pub(super) mod tls;
// Lower bounds -- we could/should maybe move this to a separate query in `lower`
let type_alias_data = db.type_alias_data(type_alias);
let generic_params = generics(db.upcast(), type_alias.into());
- let bound_vars = Substs::bound_vars(&generic_params);
+ let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db.upcast());
let ctx = crate::TyLoweringContext::new(db, &resolver)
.with_type_param_mode(crate::lower::TypeParamLoweringMode::Variable);
let trait_data = db.trait_data(trait_);
debug!("trait {:?} = {:?}", trait_id, trait_data.name);
let generic_params = generics(db.upcast(), trait_.into());
- let bound_vars = Substs::bound_vars(&generic_params);
+ let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
let flags = chalk_rust_ir::TraitFlags {
auto: trait_data.auto,
upstream: trait_.lookup(db.upcast()).container.module(db.upcast()).krate != krate,
.as_generic_def()
.map(|generic_def| {
let generic_params = generics(db.upcast(), generic_def);
- let bound_vars = Substs::bound_vars(&generic_params);
+ let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
convert_where_clauses(db, generic_def, &bound_vars)
})
.unwrap_or_else(Vec::new);
let impl_data = db.impl_data(impl_id);
let generic_params = generics(db.upcast(), impl_id.into());
- let bound_vars = Substs::bound_vars(&generic_params);
+ let bound_vars = Substs::bound_vars(&generic_params, DebruijnIndex::INNERMOST);
let trait_ = trait_ref.trait_;
let impl_type = if impl_id.lookup(db.upcast()).container.module(db.upcast()).krate == krate {
chalk_rust_ir::ImplType::Local