mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-15 17:28:09 +00:00
Align InEnvironment with Chalk
This in particular means storing a chalk_ir::Environment, not our TraitEnvironment. This makes InEnvironment not usable for Type, where we need to keep the full TraitEnvironment.
This commit is contained in:
parent
f7be314579
commit
c4fd3f47f5
10 changed files with 94 additions and 123 deletions
|
@ -217,7 +217,7 @@ impl HirDisplay for Variant {
|
|||
|
||||
impl HirDisplay for Type {
|
||||
fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
|
||||
self.ty.value.hir_fmt(f)
|
||||
self.ty.hir_fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ use hir_ty::{
|
|||
traits::{FnTrait, Solution, SolutionVariables},
|
||||
AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast,
|
||||
DebruijnIndex, InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar,
|
||||
Substitution, Ty, TyDefId, TyKind, TyVariableKind, WhereClause,
|
||||
Substitution, TraitEnvironment, Ty, TyDefId, TyKind, TyVariableKind, WhereClause,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
@ -851,13 +851,7 @@ impl Function {
|
|||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, type_ref)| {
|
||||
let ty = Type {
|
||||
krate,
|
||||
ty: InEnvironment {
|
||||
value: ctx.lower_ty(type_ref),
|
||||
environment: environment.clone(),
|
||||
},
|
||||
};
|
||||
let ty = Type { krate, env: environment.clone(), ty: ctx.lower_ty(type_ref) };
|
||||
Param { func: self, ty, idx }
|
||||
})
|
||||
.collect()
|
||||
|
@ -1540,8 +1534,8 @@ impl Impl {
|
|||
inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
|
||||
}
|
||||
|
||||
pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty }: Type) -> Vec<Impl> {
|
||||
let def_crates = match ty.value.def_crates(db, krate) {
|
||||
pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> {
|
||||
let def_crates = match ty.def_crates(db, krate) {
|
||||
Some(def_crates) => def_crates,
|
||||
None => return Vec::new(),
|
||||
};
|
||||
|
@ -1549,14 +1543,14 @@ impl Impl {
|
|||
let filter = |impl_def: &Impl| {
|
||||
let target_ty = impl_def.target_ty(db);
|
||||
let rref = target_ty.remove_ref();
|
||||
ty.value.equals_ctor(rref.as_ref().map_or(&target_ty.ty.value, |it| &it.ty.value))
|
||||
ty.equals_ctor(rref.as_ref().map_or(&target_ty.ty, |it| &it.ty))
|
||||
};
|
||||
|
||||
let mut all = Vec::new();
|
||||
def_crates.iter().for_each(|&id| {
|
||||
all.extend(db.inherent_impls_in_crate(id).all_impls().map(Self::from).filter(filter))
|
||||
});
|
||||
let fp = TyFingerprint::for_impl(&ty.value);
|
||||
let fp = TyFingerprint::for_impl(&ty);
|
||||
for id in def_crates
|
||||
.iter()
|
||||
.flat_map(|&id| Crate { id }.transitive_reverse_dependencies(db))
|
||||
|
@ -1643,7 +1637,8 @@ impl Impl {
|
|||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct Type {
|
||||
krate: CrateId,
|
||||
ty: InEnvironment<Ty>,
|
||||
env: Arc<TraitEnvironment>,
|
||||
ty: Ty,
|
||||
}
|
||||
|
||||
impl Type {
|
||||
|
@ -1663,14 +1658,14 @@ impl Type {
|
|||
) -> Type {
|
||||
let environment =
|
||||
resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
|
||||
Type { krate, ty: InEnvironment { value: ty, environment } }
|
||||
Type { krate, env: environment, ty }
|
||||
}
|
||||
|
||||
fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
|
||||
let resolver = lexical_env.resolver(db.upcast());
|
||||
let environment =
|
||||
resolver.generic_def().map_or_else(Default::default, |d| db.trait_environment(d));
|
||||
Type { krate, ty: InEnvironment { value: ty, environment } }
|
||||
Type { krate, env: environment, ty }
|
||||
}
|
||||
|
||||
fn from_def(
|
||||
|
@ -1684,29 +1679,29 @@ impl Type {
|
|||
}
|
||||
|
||||
pub fn is_unit(&self) -> bool {
|
||||
matches!(self.ty.value.interned(&Interner), TyKind::Tuple(0, ..))
|
||||
matches!(self.ty.interned(&Interner), TyKind::Tuple(0, ..))
|
||||
}
|
||||
pub fn is_bool(&self) -> bool {
|
||||
matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Bool))
|
||||
matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Bool))
|
||||
}
|
||||
|
||||
pub fn is_mutable_reference(&self) -> bool {
|
||||
matches!(self.ty.value.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
|
||||
matches!(self.ty.interned(&Interner), TyKind::Ref(hir_ty::Mutability::Mut, ..))
|
||||
}
|
||||
|
||||
pub fn is_usize(&self) -> bool {
|
||||
matches!(self.ty.value.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
|
||||
matches!(self.ty.interned(&Interner), TyKind::Scalar(Scalar::Uint(UintTy::Usize)))
|
||||
}
|
||||
|
||||
pub fn remove_ref(&self) -> Option<Type> {
|
||||
match &self.ty.value.interned(&Interner) {
|
||||
match &self.ty.interned(&Interner) {
|
||||
TyKind::Ref(.., ty) => Some(self.derived(ty.clone())),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_unknown(&self) -> bool {
|
||||
self.ty.value.is_unknown()
|
||||
self.ty.is_unknown()
|
||||
}
|
||||
|
||||
/// Checks that particular type `ty` implements `std::future::Future`.
|
||||
|
@ -1723,14 +1718,12 @@ impl Type {
|
|||
None => return false,
|
||||
};
|
||||
|
||||
let canonical_ty = Canonical {
|
||||
value: self.ty.value.clone(),
|
||||
binders: CanonicalVarKinds::empty(&Interner),
|
||||
};
|
||||
let canonical_ty =
|
||||
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
|
||||
method_resolution::implements_trait(
|
||||
&canonical_ty,
|
||||
db,
|
||||
self.ty.environment.clone(),
|
||||
self.env.clone(),
|
||||
krate,
|
||||
std_future_trait,
|
||||
)
|
||||
|
@ -1748,14 +1741,12 @@ impl Type {
|
|||
None => return false,
|
||||
};
|
||||
|
||||
let canonical_ty = Canonical {
|
||||
value: self.ty.value.clone(),
|
||||
binders: CanonicalVarKinds::empty(&Interner),
|
||||
};
|
||||
let canonical_ty =
|
||||
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
|
||||
method_resolution::implements_trait_unique(
|
||||
&canonical_ty,
|
||||
db,
|
||||
self.ty.environment.clone(),
|
||||
self.env.clone(),
|
||||
krate,
|
||||
fnonce_trait,
|
||||
)
|
||||
|
@ -1765,16 +1756,13 @@ impl Type {
|
|||
let trait_ref = hir_ty::TraitRef {
|
||||
trait_id: hir_ty::to_chalk_trait_id(trait_.id),
|
||||
substitution: Substitution::build_for_def(db, trait_.id)
|
||||
.push(self.ty.value.clone())
|
||||
.fill(args.iter().map(|t| t.ty.value.clone()))
|
||||
.push(self.ty.clone())
|
||||
.fill(args.iter().map(|t| t.ty.clone()))
|
||||
.build(),
|
||||
};
|
||||
|
||||
let goal = Canonical {
|
||||
value: hir_ty::InEnvironment::new(
|
||||
self.ty.environment.clone(),
|
||||
trait_ref.cast(&Interner),
|
||||
),
|
||||
value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)),
|
||||
binders: CanonicalVarKinds::empty(&Interner),
|
||||
};
|
||||
|
||||
|
@ -1789,12 +1777,12 @@ impl Type {
|
|||
alias: TypeAlias,
|
||||
) -> Option<Type> {
|
||||
let subst = Substitution::build_for_def(db, trait_.id)
|
||||
.push(self.ty.value.clone())
|
||||
.fill(args.iter().map(|t| t.ty.value.clone()))
|
||||
.push(self.ty.clone())
|
||||
.fill(args.iter().map(|t| t.ty.clone()))
|
||||
.build();
|
||||
let goal = Canonical::new(
|
||||
InEnvironment::new(
|
||||
self.ty.environment.clone(),
|
||||
self.env.env.clone(),
|
||||
AliasEq {
|
||||
alias: AliasTy::Projection(ProjectionTy {
|
||||
associated_ty_id: to_assoc_type_id(alias.id),
|
||||
|
@ -1826,22 +1814,22 @@ impl Type {
|
|||
}
|
||||
|
||||
pub fn as_callable(&self, db: &dyn HirDatabase) -> Option<Callable> {
|
||||
let def = self.ty.value.callable_def(db);
|
||||
let def = self.ty.callable_def(db);
|
||||
|
||||
let sig = self.ty.value.callable_sig(db)?;
|
||||
let sig = self.ty.callable_sig(db)?;
|
||||
Some(Callable { ty: self.clone(), sig, def, is_bound_method: false })
|
||||
}
|
||||
|
||||
pub fn is_closure(&self) -> bool {
|
||||
matches!(&self.ty.value.interned(&Interner), TyKind::Closure { .. })
|
||||
matches!(&self.ty.interned(&Interner), TyKind::Closure { .. })
|
||||
}
|
||||
|
||||
pub fn is_fn(&self) -> bool {
|
||||
matches!(&self.ty.value.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. })
|
||||
matches!(&self.ty.interned(&Interner), TyKind::FnDef(..) | TyKind::Function { .. })
|
||||
}
|
||||
|
||||
pub fn is_packed(&self, db: &dyn HirDatabase) -> bool {
|
||||
let adt_id = match self.ty.value.interned(&Interner) {
|
||||
let adt_id = match self.ty.interned(&Interner) {
|
||||
&TyKind::Adt(hir_ty::AdtId(adt_id), ..) => adt_id,
|
||||
_ => return false,
|
||||
};
|
||||
|
@ -1854,11 +1842,11 @@ impl Type {
|
|||
}
|
||||
|
||||
pub fn is_raw_ptr(&self) -> bool {
|
||||
matches!(&self.ty.value.interned(&Interner), TyKind::Raw(..))
|
||||
matches!(&self.ty.interned(&Interner), TyKind::Raw(..))
|
||||
}
|
||||
|
||||
pub fn contains_unknown(&self) -> bool {
|
||||
return go(&self.ty.value);
|
||||
return go(&self.ty);
|
||||
|
||||
fn go(ty: &Ty) -> bool {
|
||||
match ty.interned(&Interner) {
|
||||
|
@ -1890,7 +1878,7 @@ impl Type {
|
|||
}
|
||||
|
||||
pub fn fields(&self, db: &dyn HirDatabase) -> Vec<(Field, Type)> {
|
||||
let (variant_id, substs) = match self.ty.value.interned(&Interner) {
|
||||
let (variant_id, substs) = match self.ty.interned(&Interner) {
|
||||
&TyKind::Adt(hir_ty::AdtId(AdtId::StructId(s)), ref substs) => (s.into(), substs),
|
||||
&TyKind::Adt(hir_ty::AdtId(AdtId::UnionId(u)), ref substs) => (u.into(), substs),
|
||||
_ => return Vec::new(),
|
||||
|
@ -1907,7 +1895,7 @@ impl Type {
|
|||
}
|
||||
|
||||
pub fn tuple_fields(&self, _db: &dyn HirDatabase) -> Vec<Type> {
|
||||
if let TyKind::Tuple(_, substs) = &self.ty.value.interned(&Interner) {
|
||||
if let TyKind::Tuple(_, substs) = &self.ty.interned(&Interner) {
|
||||
substs.iter().map(|ty| self.derived(ty.clone())).collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
|
@ -1917,12 +1905,10 @@ impl Type {
|
|||
pub fn autoderef<'a>(&'a self, db: &'a dyn HirDatabase) -> impl Iterator<Item = Type> + 'a {
|
||||
// There should be no inference vars in types passed here
|
||||
// FIXME check that?
|
||||
let canonical = Canonical {
|
||||
value: self.ty.value.clone(),
|
||||
binders: CanonicalVarKinds::empty(&Interner),
|
||||
};
|
||||
let environment = self.ty.environment.clone();
|
||||
let ty = InEnvironment { value: canonical, environment };
|
||||
let canonical =
|
||||
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
|
||||
let environment = self.env.env.clone();
|
||||
let ty = InEnvironment { goal: canonical, environment };
|
||||
autoderef(db, Some(self.krate), ty)
|
||||
.map(|canonical| canonical.value)
|
||||
.map(move |ty| self.derived(ty))
|
||||
|
@ -1936,10 +1922,10 @@ impl Type {
|
|||
krate: Crate,
|
||||
mut callback: impl FnMut(AssocItem) -> Option<T>,
|
||||
) -> Option<T> {
|
||||
for krate in self.ty.value.def_crates(db, krate.id)? {
|
||||
for krate in self.ty.def_crates(db, krate.id)? {
|
||||
let impls = db.inherent_impls_in_crate(krate);
|
||||
|
||||
for impl_def in impls.for_self_ty(&self.ty.value) {
|
||||
for impl_def in impls.for_self_ty(&self.ty) {
|
||||
for &item in db.impl_data(*impl_def).items.iter() {
|
||||
if let Some(result) = callback(item.into()) {
|
||||
return Some(result);
|
||||
|
@ -1952,7 +1938,6 @@ impl Type {
|
|||
|
||||
pub fn type_parameters(&self) -> impl Iterator<Item = Type> + '_ {
|
||||
self.ty
|
||||
.value
|
||||
.strip_references()
|
||||
.substs()
|
||||
.into_iter()
|
||||
|
@ -1971,12 +1956,10 @@ impl Type {
|
|||
// There should be no inference vars in types passed here
|
||||
// FIXME check that?
|
||||
// FIXME replace Unknown by bound vars here
|
||||
let canonical = Canonical {
|
||||
value: self.ty.value.clone(),
|
||||
binders: CanonicalVarKinds::empty(&Interner),
|
||||
};
|
||||
let canonical =
|
||||
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
|
||||
|
||||
let env = self.ty.environment.clone();
|
||||
let env = self.env.clone();
|
||||
let krate = krate.id;
|
||||
|
||||
method_resolution::iterate_method_candidates(
|
||||
|
@ -2005,12 +1988,10 @@ impl Type {
|
|||
// There should be no inference vars in types passed here
|
||||
// FIXME check that?
|
||||
// FIXME replace Unknown by bound vars here
|
||||
let canonical = Canonical {
|
||||
value: self.ty.value.clone(),
|
||||
binders: CanonicalVarKinds::empty(&Interner),
|
||||
};
|
||||
let canonical =
|
||||
Canonical { value: self.ty.clone(), binders: CanonicalVarKinds::empty(&Interner) };
|
||||
|
||||
let env = self.ty.environment.clone();
|
||||
let env = self.env.clone();
|
||||
let krate = krate.id;
|
||||
|
||||
method_resolution::iterate_method_candidates(
|
||||
|
@ -2026,16 +2007,16 @@ impl Type {
|
|||
}
|
||||
|
||||
pub fn as_adt(&self) -> Option<Adt> {
|
||||
let (adt, _subst) = self.ty.value.as_adt()?;
|
||||
let (adt, _subst) = self.ty.as_adt()?;
|
||||
Some(adt.into())
|
||||
}
|
||||
|
||||
pub fn as_dyn_trait(&self) -> Option<Trait> {
|
||||
self.ty.value.dyn_trait().map(Into::into)
|
||||
self.ty.dyn_trait().map(Into::into)
|
||||
}
|
||||
|
||||
pub fn as_impl_traits(&self, db: &dyn HirDatabase) -> Option<Vec<Trait>> {
|
||||
self.ty.value.impl_trait_bounds(db).map(|it| {
|
||||
self.ty.impl_trait_bounds(db).map(|it| {
|
||||
it.into_iter()
|
||||
.filter_map(|pred| match pred.skip_binders() {
|
||||
hir_ty::WhereClause::Implemented(trait_ref) => {
|
||||
|
@ -2048,14 +2029,11 @@ impl Type {
|
|||
}
|
||||
|
||||
pub fn as_associated_type_parent_trait(&self, db: &dyn HirDatabase) -> Option<Trait> {
|
||||
self.ty.value.associated_type_parent_trait(db).map(Into::into)
|
||||
self.ty.associated_type_parent_trait(db).map(Into::into)
|
||||
}
|
||||
|
||||
fn derived(&self, ty: Ty) -> Type {
|
||||
Type {
|
||||
krate: self.krate,
|
||||
ty: InEnvironment { value: ty, environment: self.ty.environment.clone() },
|
||||
}
|
||||
Type { krate: self.krate, env: self.env.clone(), ty }
|
||||
}
|
||||
|
||||
pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) {
|
||||
|
@ -2094,7 +2072,7 @@ impl Type {
|
|||
}
|
||||
|
||||
fn walk_type(db: &dyn HirDatabase, type_: &Type, cb: &mut impl FnMut(Type)) {
|
||||
let ty = type_.ty.value.strip_references();
|
||||
let ty = type_.ty.strip_references();
|
||||
match ty.interned(&Interner) {
|
||||
TyKind::Adt(..) => {
|
||||
cb(type_.derived(ty.clone()));
|
||||
|
|
|
@ -27,9 +27,9 @@ pub fn autoderef<'a>(
|
|||
krate: Option<CrateId>,
|
||||
ty: InEnvironment<Canonical<Ty>>,
|
||||
) -> impl Iterator<Item = Canonical<Ty>> + 'a {
|
||||
let InEnvironment { value: ty, environment } = ty;
|
||||
let InEnvironment { goal: ty, environment } = ty;
|
||||
successors(Some(ty), move |ty| {
|
||||
deref(db, krate?, InEnvironment { value: ty, environment: environment.clone() })
|
||||
deref(db, krate?, InEnvironment { goal: ty, environment: environment.clone() })
|
||||
})
|
||||
.take(AUTODEREF_RECURSION_LIMIT)
|
||||
}
|
||||
|
@ -39,8 +39,8 @@ pub(crate) fn deref(
|
|||
krate: CrateId,
|
||||
ty: InEnvironment<&Canonical<Ty>>,
|
||||
) -> Option<Canonical<Ty>> {
|
||||
if let Some(derefed) = ty.value.value.builtin_deref() {
|
||||
Some(Canonical { value: derefed, binders: ty.value.binders.clone() })
|
||||
if let Some(derefed) = ty.goal.value.builtin_deref() {
|
||||
Some(Canonical { value: derefed, binders: ty.goal.binders.clone() })
|
||||
} else {
|
||||
deref_by_trait(db, krate, ty)
|
||||
}
|
||||
|
@ -67,15 +67,15 @@ fn deref_by_trait(
|
|||
// FIXME make the Canonical / bound var handling nicer
|
||||
|
||||
let parameters =
|
||||
Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build();
|
||||
Substitution::build_for_generics(&generic_params).push(ty.goal.value.clone()).build();
|
||||
|
||||
// Check that the type implements Deref at all
|
||||
let trait_ref =
|
||||
TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() };
|
||||
let implements_goal = Canonical {
|
||||
binders: ty.value.binders.clone(),
|
||||
binders: ty.goal.binders.clone(),
|
||||
value: InEnvironment {
|
||||
value: trait_ref.cast(&Interner),
|
||||
goal: trait_ref.cast(&Interner),
|
||||
environment: ty.environment.clone(),
|
||||
},
|
||||
};
|
||||
|
@ -91,20 +91,20 @@ fn deref_by_trait(
|
|||
}),
|
||||
ty: TyKind::BoundVar(BoundVar::new(
|
||||
DebruijnIndex::INNERMOST,
|
||||
ty.value.binders.len(&Interner),
|
||||
ty.goal.binders.len(&Interner),
|
||||
))
|
||||
.intern(&Interner),
|
||||
};
|
||||
|
||||
let obligation = projection.cast(&Interner);
|
||||
|
||||
let in_env = InEnvironment { value: obligation, environment: ty.environment };
|
||||
let in_env = InEnvironment { goal: obligation, environment: ty.environment };
|
||||
|
||||
let canonical = Canonical {
|
||||
value: in_env,
|
||||
binders: CanonicalVarKinds::from_iter(
|
||||
&Interner,
|
||||
ty.value.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new(
|
||||
ty.goal.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new(
|
||||
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
|
||||
chalk_ir::UniverseIndex::ROOT,
|
||||
))),
|
||||
|
@ -134,7 +134,7 @@ fn deref_by_trait(
|
|||
if vars.0.value[i - 1].interned(&Interner)
|
||||
!= &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
|
||||
{
|
||||
warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution);
|
||||
warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ fn deref_by_trait(
|
|||
})
|
||||
}
|
||||
Solution::Ambig(_) => {
|
||||
info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution);
|
||||
info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution);
|
||||
None
|
||||
}
|
||||
}
|
||||
|
|
|
@ -331,7 +331,7 @@ impl<'a> InferenceContext<'a> {
|
|||
fn resolve_obligations_as_possible(&mut self) {
|
||||
let obligations = mem::replace(&mut self.obligations, Vec::new());
|
||||
for obligation in obligations {
|
||||
let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone());
|
||||
let in_env = InEnvironment::new(self.trait_env.env.clone(), obligation.clone());
|
||||
let canonicalized = self.canonicalizer().canonicalize_obligation(in_env);
|
||||
let solution =
|
||||
self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone());
|
||||
|
|
|
@ -142,7 +142,7 @@ impl<'a> InferenceContext<'a> {
|
|||
.build();
|
||||
let trait_ref =
|
||||
TraitRef { trait_id: to_chalk_trait_id(coerce_unsized_trait), substitution: substs };
|
||||
let goal = InEnvironment::new(self.trait_env.clone(), trait_ref.cast(&Interner));
|
||||
let goal = InEnvironment::new(self.trait_env.env.clone(), trait_ref.cast(&Interner));
|
||||
|
||||
let canonicalizer = self.canonicalizer();
|
||||
let canonicalized = canonicalizer.canonicalize_obligation(goal);
|
||||
|
@ -170,8 +170,8 @@ impl<'a> InferenceContext<'a> {
|
|||
self.db,
|
||||
self.resolver.krate(),
|
||||
InEnvironment {
|
||||
value: canonicalized.value.clone(),
|
||||
environment: self.trait_env.clone(),
|
||||
goal: canonicalized.value.clone(),
|
||||
environment: self.trait_env.env.clone(),
|
||||
},
|
||||
) {
|
||||
let derefed_ty = canonicalized.decanonicalize_ty(derefed_ty.value);
|
||||
|
|
|
@ -90,12 +90,12 @@ impl<'a> InferenceContext<'a> {
|
|||
let substs =
|
||||
Substitution::build_for_generics(&generic_params).push(ty.clone()).push(arg_ty).build();
|
||||
|
||||
let trait_env = Arc::clone(&self.trait_env);
|
||||
let trait_env = self.trait_env.env.clone();
|
||||
let implements_fn_trait: DomainGoal =
|
||||
TraitRef { trait_id: to_chalk_trait_id(fn_once_trait), substitution: substs.clone() }
|
||||
.cast(&Interner);
|
||||
let goal = self.canonicalizer().canonicalize_obligation(InEnvironment {
|
||||
value: implements_fn_trait.clone(),
|
||||
goal: implements_fn_trait.clone(),
|
||||
environment: trait_env,
|
||||
});
|
||||
if self.db.trait_solve(krate, goal.value).is_some() {
|
||||
|
@ -299,8 +299,8 @@ impl<'a> InferenceContext<'a> {
|
|||
self.db,
|
||||
self.resolver.krate(),
|
||||
InEnvironment {
|
||||
value: canonicalized.value.clone(),
|
||||
environment: self.trait_env.clone(),
|
||||
goal: canonicalized.value.clone(),
|
||||
environment: self.trait_env.env.clone(),
|
||||
},
|
||||
);
|
||||
let (param_tys, ret_ty): (Vec<Ty>, Ty) = derefs
|
||||
|
@ -438,8 +438,8 @@ impl<'a> InferenceContext<'a> {
|
|||
self.db,
|
||||
self.resolver.krate(),
|
||||
InEnvironment {
|
||||
value: canonicalized.value.clone(),
|
||||
environment: self.trait_env.clone(),
|
||||
goal: canonicalized.value.clone(),
|
||||
environment: self.trait_env.env.clone(),
|
||||
},
|
||||
)
|
||||
.find_map(|derefed_ty| {
|
||||
|
@ -538,8 +538,8 @@ impl<'a> InferenceContext<'a> {
|
|||
self.db,
|
||||
krate,
|
||||
InEnvironment {
|
||||
value: &canonicalized.value,
|
||||
environment: self.trait_env.clone(),
|
||||
goal: &canonicalized.value,
|
||||
environment: self.trait_env.env.clone(),
|
||||
},
|
||||
) {
|
||||
Some(derefed_ty) => {
|
||||
|
|
|
@ -98,15 +98,12 @@ impl<'a, 'b> Canonicalizer<'a, 'b> {
|
|||
mut self,
|
||||
obligation: InEnvironment<DomainGoal>,
|
||||
) -> Canonicalized<InEnvironment<DomainGoal>> {
|
||||
let result = match obligation.value {
|
||||
let result = match obligation.goal {
|
||||
DomainGoal::Holds(wc) => {
|
||||
DomainGoal::Holds(self.do_canonicalize(wc, DebruijnIndex::INNERMOST))
|
||||
}
|
||||
};
|
||||
self.into_canonicalized(InEnvironment {
|
||||
value: result,
|
||||
environment: obligation.environment,
|
||||
})
|
||||
self.into_canonicalized(InEnvironment { goal: result, environment: obligation.environment })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -376,7 +376,7 @@ fn iterate_method_candidates_impl(
|
|||
// Also note that when we've got a receiver like &S, even if the method we
|
||||
// find in the end takes &self, we still do the autoderef step (just as
|
||||
// rustc does an autoderef and then autoref again).
|
||||
let ty = InEnvironment { value: ty.clone(), environment: env.clone() };
|
||||
let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
|
||||
|
||||
// We have to be careful about the order we're looking at candidates
|
||||
// in here. Consider the case where we're resolving `x.clone()`
|
||||
|
@ -622,7 +622,7 @@ pub fn resolve_indexing_op(
|
|||
krate: CrateId,
|
||||
index_trait: TraitId,
|
||||
) -> Option<Canonical<Ty>> {
|
||||
let ty = InEnvironment { value: ty.clone(), environment: env.clone() };
|
||||
let ty = InEnvironment { goal: ty.clone(), environment: env.env.clone() };
|
||||
let deref_chain = autoderef_method_receiver(db, krate, ty);
|
||||
for ty in deref_chain {
|
||||
let goal = generic_implements_goal(db, env.clone(), index_trait, ty.clone());
|
||||
|
@ -794,7 +794,7 @@ fn generic_implements_goal(
|
|||
let obligation = trait_ref.cast(&Interner);
|
||||
Canonical {
|
||||
binders: CanonicalVarKinds::from_iter(&Interner, kinds),
|
||||
value: InEnvironment::new(env, obligation),
|
||||
value: InEnvironment::new(env.env.clone(), obligation),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
//! Trait solving using Chalk.
|
||||
use std::env::var;
|
||||
use std::sync::Arc;
|
||||
|
||||
use base_db::CrateId;
|
||||
use chalk_ir::cast::Cast;
|
||||
|
@ -44,7 +43,7 @@ pub struct TraitEnvironment {
|
|||
// When we're using Chalk's Ty we can make this a BTreeMap since it's Ord,
|
||||
// but for now it's too annoying...
|
||||
pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>,
|
||||
pub(crate) env: chalk_ir::Environment<Interner>,
|
||||
pub env: chalk_ir::Environment<Interner>,
|
||||
}
|
||||
|
||||
impl TraitEnvironment {
|
||||
|
@ -74,13 +73,13 @@ impl Default for TraitEnvironment {
|
|||
/// Something (usually a goal), along with an environment.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct InEnvironment<T> {
|
||||
pub environment: Arc<TraitEnvironment>,
|
||||
pub value: T,
|
||||
pub environment: chalk_ir::Environment<Interner>,
|
||||
pub goal: T,
|
||||
}
|
||||
|
||||
impl<T> InEnvironment<T> {
|
||||
pub fn new(environment: Arc<TraitEnvironment>, value: T) -> InEnvironment<T> {
|
||||
InEnvironment { environment, value }
|
||||
pub fn new(environment: chalk_ir::Environment<Interner>, value: T) -> InEnvironment<T> {
|
||||
InEnvironment { environment, goal: value }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,18 +125,18 @@ pub(crate) fn trait_solve_query(
|
|||
krate: CrateId,
|
||||
goal: Canonical<InEnvironment<DomainGoal>>,
|
||||
) -> Option<Solution> {
|
||||
let _p = profile::span("trait_solve_query").detail(|| match &goal.value.value {
|
||||
let _p = profile::span("trait_solve_query").detail(|| match &goal.value.goal {
|
||||
DomainGoal::Holds(WhereClause::Implemented(it)) => {
|
||||
db.trait_data(it.hir_trait_id()).name.to_string()
|
||||
}
|
||||
DomainGoal::Holds(WhereClause::AliasEq(_)) => "alias_eq".to_string(),
|
||||
});
|
||||
log::info!("trait_solve_query({})", goal.value.value.display(db));
|
||||
log::info!("trait_solve_query({})", goal.value.goal.display(db));
|
||||
|
||||
if let DomainGoal::Holds(WhereClause::AliasEq(AliasEq {
|
||||
alias: AliasTy::Projection(projection_ty),
|
||||
..
|
||||
})) = &goal.value.value
|
||||
})) = &goal.value.goal
|
||||
{
|
||||
if let TyKind::BoundVar(_) = &projection_ty.substitution[0].interned(&Interner) {
|
||||
// Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
|
||||
|
|
|
@ -455,10 +455,7 @@ where
|
|||
type Chalk = chalk_ir::InEnvironment<T::Chalk>;
|
||||
|
||||
fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::InEnvironment<T::Chalk> {
|
||||
chalk_ir::InEnvironment {
|
||||
environment: self.environment.env.clone(),
|
||||
goal: self.value.to_chalk(db),
|
||||
}
|
||||
chalk_ir::InEnvironment { environment: self.environment, goal: self.goal.to_chalk(db) }
|
||||
}
|
||||
|
||||
fn from_chalk(
|
||||
|
|
Loading…
Reference in a new issue