Fixes #8150.
assert_eq!(subst.len(), self.num_binders);
self.value.subst_bound_vars(subst)
}
-
- /// Substitutes just a prefix of the variables (shifting the rest).
- pub fn subst_prefix(self, subst: &Substitution) -> Binders<T> {
- assert!(subst.len() < self.num_binders);
- Binders::new(self.num_binders - subst.len(), self.value.subst_bound_vars(subst))
- }
}
impl<T: TypeWalk> TypeWalk for Binders<T> {
pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
CallableSig {
- params_and_return: fn_ptr.substs.interned(&Interner).iter().cloned().collect(),
+ // FIXME: what to do about lifetime params?
+ params_and_return: fn_ptr
+ .substs
+ .clone()
+ .shift_bound_vars_out(DebruijnIndex::ONE)
+ .interned(&Interner)
+ .iter()
+ .cloned()
+ .collect(),
is_varargs: fn_ptr.sig.variadic,
}
}
DebruijnIndex::INNERMOST,
)
}
+
+ /// Shifts debruijn indices of `TyKind::Bound` vars out (down) by `n`.
+ fn shift_bound_vars_out(self, n: DebruijnIndex) -> Self
+ where
+ Self: Sized + std::fmt::Debug,
+ {
+ self.fold_binders(
+ &mut |ty, binders| match ty.interned(&Interner) {
+ TyKind::BoundVar(bound) if bound.debruijn >= binders => {
+ TyKind::BoundVar(bound.shifted_out_to(n).unwrap_or(bound.clone()))
+ .intern(&Interner)
+ }
+ _ => ty,
+ },
+ DebruijnIndex::INNERMOST,
+ )
+ }
}
impl TypeWalk for Ty {
let traits_from_env: Vec<_> = match res {
TypeNs::SelfType(impl_id) => match db.impl_trait(impl_id) {
None => vec![],
- Some(trait_ref) => vec![trait_ref.value],
+ // FIXME: how to correctly handle higher-ranked bounds here?
+ Some(trait_ref) => vec![trait_ref.value.shift_bound_vars_out(DebruijnIndex::ONE)],
},
TypeNs::GenericParam(param_id) => {
let predicates = db.generic_predicates_for_param(param_id);
let mut traits_: Vec<_> = predicates
.iter()
.filter_map(|pred| match &pred.value.value {
- WhereClause::Implemented(tr) => Some(tr.clone()),
+ // FIXME: how to correctly handle higher-ranked bounds here?
+ WhereClause::Implemented(tr) => {
+ Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE))
+ }
_ => None,
})
.collect();
if db.type_alias_data(t).is_extern {
Binders::new(0, TyKind::ForeignType(crate::to_foreign_def_id(t)).intern(&Interner))
} else {
- let substs = Substitution::bound_vars(&generics, DebruijnIndex::INNERMOST);
let type_ref = &db.type_alias_data(t).type_ref;
let inner = ctx.lower_ty(type_ref.as_ref().unwrap_or(&TypeRef::Error));
- Binders::new(substs.len(), inner)
+ Binders::new(generics.len(), inner)
}
}
method_resolution::{TyFingerprint, ALL_FLOAT_FPS, ALL_INT_FPS},
to_assoc_type_id, to_chalk_trait_id,
utils::generics,
- AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, DebruijnIndex, FnDefId, ProjectionTy,
- Substitution, TraitRef, Ty, TyKind, WhereClause,
+ AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, ProjectionTy, Substitution,
+ TraitRef, Ty, TyKind, WhereClause,
};
use mapping::{
convert_where_clauses, generic_predicate_to_inline_bound, make_binders, TypeAliasAsValue,
) -> chalk_ir::Binders<rust_ir::FnDefInputsAndOutputDatum<Interner>> {
let sig_ty: Ty =
from_chalk(self.db, substs.at(&Interner, 0).assert_ty_ref(&Interner).clone());
- let sig = CallableSig::from_substs(
- &sig_ty.substs().expect("first closure param should be fn ptr"),
- );
+ let sig = &sig_ty.callable_sig(self.db).expect("first closure param should be fn ptr");
let io = rust_ir::FnDefInputsAndOutputDatum {
argument_types: sig.params().iter().map(|ty| ty.clone().to_chalk(self.db)).collect(),
return_type: sig.ret().clone().to_chalk(self.db),
//! query, but can't be computed directly from `*Data` (ie, which need a `db`).
use std::sync::Arc;
+use chalk_ir::DebruijnIndex;
use hir_def::{
adt::VariantData,
db::DefDatabase,
};
use hir_expand::name::{name, Name};
-use crate::{db::HirDatabase, TraitRef, WhereClause};
+use crate::{db::HirDatabase, TraitRef, TypeWalk, WhereClause};
fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
let resolver = trait_.resolver(db);
.iter()
.filter_map(|pred| {
pred.as_ref().filter_map(|pred| match pred.skip_binders() {
- WhereClause::Implemented(tr) => Some(tr.clone()),
+ // FIXME: how to correctly handle higher-ranked bounds here?
+ WhereClause::Implemented(tr) => {
+ Some(tr.clone().shift_bound_vars_out(DebruijnIndex::ONE))
+ }
_ => None,
})
})