From f7be314579db29f64ef660aef1896da33d420ad6 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 21 Mar 2021 20:05:38 +0100 Subject: Align Canonical more with Chalk's version In particular, use chalk_ir::CanonicalVarKinds. --- crates/hir_ty/src/infer/unify.rs | 44 +++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 14 deletions(-) (limited to 'crates/hir_ty/src/infer') diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 35b0a2059..7595b46cf 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs @@ -2,13 +2,13 @@ use std::borrow::Cow; -use chalk_ir::{FloatTy, IntTy, TyVariableKind}; +use chalk_ir::{FloatTy, IntTy, TyVariableKind, UniverseIndex, VariableKind}; use ena::unify::{InPlaceUnificationTable, NoError, UnifyKey, UnifyValue}; use super::{DomainGoal, InferenceContext}; use crate::{ - AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, FnPointer, InEnvironment, InferenceVar, - Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause, + AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, + InEnvironment, InferenceVar, Interner, Scalar, Substitution, Ty, TyKind, TypeWalk, WhereClause, }; impl<'a> InferenceContext<'a> { @@ -76,8 +76,17 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { } fn into_canonicalized(self, result: T) -> Canonicalized { - let kinds = self.free_vars.iter().map(|&(_, k)| k).collect(); - Canonicalized { value: Canonical { value: result, kinds }, free_vars: self.free_vars } + let kinds = self + .free_vars + .iter() + .map(|&(_, k)| chalk_ir::WithKind::new(VariableKind::Ty(k), UniverseIndex::ROOT)); + Canonicalized { + value: Canonical { + value: result, + binders: CanonicalVarKinds::from_iter(&Interner, kinds), + }, + free_vars: self.free_vars, + } } pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized { @@ -125,12 +134,19 @@ impl Canonicalized { // the solution may contain new variables, which we need to convert to new inference vars let new_vars = Substitution( solution - .kinds - .iter() - .map(|k| match k { - TyVariableKind::General => ctx.table.new_type_var(), - TyVariableKind::Integer => ctx.table.new_integer_var(), - TyVariableKind::Float => ctx.table.new_float_var(), + .binders + .iter(&Interner) + .map(|k| match k.kind { + VariableKind::Ty(TyVariableKind::General) => ctx.table.new_type_var(), + VariableKind::Ty(TyVariableKind::Integer) => ctx.table.new_integer_var(), + VariableKind::Ty(TyVariableKind::Float) => ctx.table.new_float_var(), + // HACK: Chalk can sometimes return new lifetime variables. We + // want to just skip them, but to not mess up the indices of + // other variables, we'll just create a new type variable in + // their place instead. This should not matter (we never see the + // actual *uses* of the lifetime variable). + VariableKind::Lifetime => ctx.table.new_type_var(), + _ => panic!("const variable in solution"), }) .collect(), ); @@ -147,8 +163,8 @@ impl Canonicalized { pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option { let mut table = InferenceTable::new(); let vars = Substitution( - tys.kinds - .iter() + tys.binders + .iter(&Interner) // we always use type vars here because we want everything to // fallback to Unknown in the end (kind of hacky, as below) .map(|_| table.new_type_var()) @@ -170,7 +186,7 @@ pub(crate) fn unify(tys: &Canonical<(Ty, Ty)>) -> Option { } } Some( - Substitution::builder(tys.kinds.len()) + Substitution::builder(tys.binders.len(&Interner)) .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) .build(), ) -- cgit v1.2.3 From c4fd3f47f5b4f34476f8f085f2412a46aa0fd24f Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 21 Mar 2021 20:19:07 +0100 Subject: 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. --- crates/hir_ty/src/infer/coerce.rs | 6 +++--- crates/hir_ty/src/infer/expr.rs | 16 ++++++++-------- crates/hir_ty/src/infer/unify.rs | 7 ++----- 3 files changed, 13 insertions(+), 16 deletions(-) (limited to 'crates/hir_ty/src/infer') diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 07eb96573..9c62932b1 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs @@ -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); diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 17849d552..4e2a432ed 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs @@ -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) = 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) => { diff --git a/crates/hir_ty/src/infer/unify.rs b/crates/hir_ty/src/infer/unify.rs index 7595b46cf..75250a369 100644 --- a/crates/hir_ty/src/infer/unify.rs +++ b/crates/hir_ty/src/infer/unify.rs @@ -98,15 +98,12 @@ impl<'a, 'b> Canonicalizer<'a, 'b> { mut self, obligation: InEnvironment, ) -> Canonicalized> { - 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 }) } } -- cgit v1.2.3