From b03969cda92661ad67897fee0ba16c1cc61830ea Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 6 Apr 2021 23:46:32 +0200 Subject: [PATCH] Remove `SolutionVariables`, add ConstrainedSubst analogous to Chalk ... just missing the constraints. --- crates/hir/src/lib.rs | 8 ++++---- crates/hir_ty/src/autoderef.rs | 10 +++++----- crates/hir_ty/src/infer.rs | 15 +++++++++++---- crates/hir_ty/src/infer/coerce.rs | 11 +++++++++-- crates/hir_ty/src/traits.rs | 16 ++++------------ crates/hir_ty/src/traits/chalk/mapping.rs | 16 ++++++++++++++-- crates/hir_ty/src/types.rs | 10 ++++++---- 7 files changed, 53 insertions(+), 33 deletions(-) diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 8d00f7401b..caa22dace3 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -58,9 +58,8 @@ use hir_ty::{ subst_prefix, traits::FnTrait, AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, - DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Solution, - SolutionVariables, Substitution, TraitEnvironment, Ty, TyBuilder, TyDefId, TyExt, TyKind, - TyVariableKind, WhereClause, + DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Solution, Substitution, + TraitEnvironment, Ty, TyBuilder, TyDefId, TyExt, TyKind, TyVariableKind, WhereClause, }; use itertools::Itertools; use rustc_hash::FxHashSet; @@ -1822,8 +1821,9 @@ impl Type { ); match db.trait_solve(self.krate, goal)? { - Solution::Unique(SolutionVariables(subst)) => subst + Solution::Unique(s) => s .value + .subst .interned() .first() .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())), diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs index c5890e24df..80e192a575 100644 --- a/crates/hir_ty/src/autoderef.rs +++ b/crates/hir_ty/src/autoderef.rs @@ -120,8 +120,8 @@ fn deref_by_trait( // assumptions will be broken. We would need to properly introduce // new variables in that case - for i in 1..vars.0.binders.len(&Interner) { - if vars.0.value.at(&Interner, i - 1).assert_ty_ref(&Interner).kind(&Interner) + for i in 1..vars.binders.len(&Interner) { + if vars.value.subst.at(&Interner, i - 1).assert_ty_ref(&Interner).kind(&Interner) != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) { warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution); @@ -130,12 +130,12 @@ fn deref_by_trait( } Some(Canonical { value: vars - .0 .value - .at(&Interner, vars.0.value.len(&Interner) - 1) + .subst + .at(&Interner, vars.value.subst.len(&Interner) - 1) .assert_ty_ref(&Interner) .clone(), - binders: vars.0.binders.clone(), + binders: vars.binders.clone(), }) } Solution::Ambig(_) => { diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index 75d633c960..7c6c3600b8 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs @@ -42,7 +42,7 @@ use super::{ }; use crate::{ db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, - to_assoc_type_id, AliasEq, AliasTy, Interner, TyBuilder, TyExt, TyKind, + to_assoc_type_id, AliasEq, AliasTy, Canonical, Interner, TyBuilder, TyExt, TyKind, }; // This lint has a false positive here. See the link below for details. @@ -342,11 +342,18 @@ impl<'a> InferenceContext<'a> { self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); match solution { - Some(Solution::Unique(substs)) => { - canonicalized.apply_solution(self, substs.0); + Some(Solution::Unique(canonical_subst)) => { + canonicalized.apply_solution( + self, + Canonical { + binders: canonical_subst.binders, + // FIXME: handle constraints + value: canonical_subst.value.subst, + }, + ); } Some(Solution::Ambig(Guidance::Definite(substs))) => { - canonicalized.apply_solution(self, substs.0); + canonicalized.apply_solution(self, substs); self.obligations.push(obligation); } Some(_) => { diff --git a/crates/hir_ty/src/infer/coerce.rs b/crates/hir_ty/src/infer/coerce.rs index 159a53a631..f1af2a0bdc 100644 --- a/crates/hir_ty/src/infer/coerce.rs +++ b/crates/hir_ty/src/infer/coerce.rs @@ -7,7 +7,7 @@ use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; use hir_def::lang_item::LangItemTarget; -use crate::{autoderef, Interner, Solution, Ty, TyBuilder, TyExt, TyKind}; +use crate::{autoderef, Canonical, Interner, Solution, Ty, TyBuilder, TyExt, TyKind}; use super::{InEnvironment, InferenceContext}; @@ -148,7 +148,14 @@ impl<'a> InferenceContext<'a> { match solution { Solution::Unique(v) => { - canonicalized.apply_solution(self, v.0); + canonicalized.apply_solution( + self, + Canonical { + binders: v.binders, + // FIXME handle constraints + value: v.value.subst, + }, + ); } _ => return None, }; diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs index c8883485c0..3374532c34 100644 --- a/crates/hir_ty/src/traits.rs +++ b/crates/hir_ty/src/traits.rs @@ -9,7 +9,7 @@ use stdx::panic_context; use crate::{ db::HirDatabase, AliasEq, AliasTy, Canonical, DomainGoal, Guidance, HirDisplay, InEnvironment, - Solution, SolutionVariables, Ty, TyKind, WhereClause, + Solution, Ty, TyKind, WhereClause, }; use self::chalk::{from_chalk, Interner, ToChalk}; @@ -173,23 +173,15 @@ fn solution_from_chalk( db: &dyn HirDatabase, solution: chalk_solve::Solution, ) -> Solution { - let convert_subst = |subst: chalk_ir::Canonical>| { - let result = from_chalk(db, subst); - SolutionVariables(result) - }; match solution { chalk_solve::Solution::Unique(constr_subst) => { - let subst = chalk_ir::Canonical { - value: constr_subst.value.subst, - binders: constr_subst.binders, - }; - Solution::Unique(convert_subst(subst)) + Solution::Unique(from_chalk(db, constr_subst)) } chalk_solve::Solution::Ambig(chalk_solve::Guidance::Definite(subst)) => { - Solution::Ambig(Guidance::Definite(convert_subst(subst))) + Solution::Ambig(Guidance::Definite(from_chalk(db, subst))) } chalk_solve::Solution::Ambig(chalk_solve::Guidance::Suggested(subst)) => { - Solution::Ambig(Guidance::Suggested(convert_subst(subst))) + Solution::Ambig(Guidance::Suggested(from_chalk(db, subst))) } chalk_solve::Solution::Ambig(chalk_solve::Guidance::Unknown) => { Solution::Ambig(Guidance::Unknown) diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 0536b934e7..84abd99b29 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs @@ -11,8 +11,8 @@ use hir_def::{GenericDefId, TypeAliasId}; use crate::{ chalk_ext::ProjectionTyExt, db::HirDatabase, static_lifetime, AliasTy, CallableDefId, - Canonical, DomainGoal, FnPointer, GenericArg, InEnvironment, OpaqueTy, ProjectionTy, - QuantifiedWhereClause, Substitution, TraitRef, Ty, TypeWalk, WhereClause, + Canonical, ConstrainedSubst, DomainGoal, FnPointer, GenericArg, InEnvironment, OpaqueTy, + ProjectionTy, QuantifiedWhereClause, Substitution, TraitRef, Ty, TypeWalk, WhereClause, }; use super::interner::*; @@ -459,6 +459,18 @@ where } } +impl ToChalk for crate::ConstrainedSubst { + type Chalk = chalk_ir::ConstrainedSubst; + + fn to_chalk(self, _db: &dyn HirDatabase) -> Self::Chalk { + unimplemented!() + } + + fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self { + ConstrainedSubst { subst: from_chalk(db, chalk.subst) } + } +} + pub(super) fn make_binders(value: T, num_vars: usize) -> chalk_ir::Binders where T: HasInterner, diff --git a/crates/hir_ty/src/types.rs b/crates/hir_ty/src/types.rs index eac1b79000..c25bc2d6ab 100644 --- a/crates/hir_ty/src/types.rs +++ b/crates/hir_ty/src/types.rs @@ -490,14 +490,16 @@ pub struct AliasEq { } #[derive(Clone, Debug, PartialEq, Eq)] -pub struct SolutionVariables(pub Canonical); +pub struct ConstrainedSubst { + pub subst: Substitution, +} #[derive(Clone, Debug, PartialEq, Eq)] /// A (possible) solution for a proposed goal. pub enum Solution { /// The goal indeed holds, and there is a unique value for all existential /// variables. - Unique(SolutionVariables), + Unique(Canonical), /// The goal may be provable in multiple ways, but regardless we may have some guidance /// for type inference. In this case, we don't return any lifetime @@ -513,12 +515,12 @@ pub enum Guidance { /// The existential variables *must* have the given values if the goal is /// ever to hold, but that alone isn't enough to guarantee the goal will /// actually hold. - Definite(SolutionVariables), + Definite(Canonical), /// There are multiple plausible values for the existentials, but the ones /// here are suggested as the preferred choice heuristically. These should /// be used for inference fallback only. - Suggested(SolutionVariables), + Suggested(Canonical), /// There's no useful information to feed back to type inference Unknown,