Remove SolutionVariables, add ConstrainedSubst analogous to Chalk

... just missing the constraints.
This commit is contained in:
Florian Diebold 2021-04-06 23:46:32 +02:00
parent 31d2b3b9cb
commit b03969cda9
7 changed files with 53 additions and 33 deletions

View file

@ -58,9 +58,8 @@ use hir_ty::{
subst_prefix, subst_prefix,
traits::FnTrait, traits::FnTrait,
AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast,
DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Solution, DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Solution, Substitution,
SolutionVariables, Substitution, TraitEnvironment, Ty, TyBuilder, TyDefId, TyExt, TyKind, TraitEnvironment, Ty, TyBuilder, TyDefId, TyExt, TyKind, TyVariableKind, WhereClause,
TyVariableKind, WhereClause,
}; };
use itertools::Itertools; use itertools::Itertools;
use rustc_hash::FxHashSet; use rustc_hash::FxHashSet;
@ -1822,8 +1821,9 @@ impl Type {
); );
match db.trait_solve(self.krate, goal)? { match db.trait_solve(self.krate, goal)? {
Solution::Unique(SolutionVariables(subst)) => subst Solution::Unique(s) => s
.value .value
.subst
.interned() .interned()
.first() .first()
.map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())), .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())),

View file

@ -120,8 +120,8 @@ fn deref_by_trait(
// assumptions will be broken. We would need to properly introduce // assumptions will be broken. We would need to properly introduce
// new variables in that case // new variables in that case
for i in 1..vars.0.binders.len(&Interner) { for i in 1..vars.binders.len(&Interner) {
if vars.0.value.at(&Interner, i - 1).assert_ty_ref(&Interner).kind(&Interner) if vars.value.subst.at(&Interner, i - 1).assert_ty_ref(&Interner).kind(&Interner)
!= &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1))
{ {
warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution); warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution);
@ -130,12 +130,12 @@ fn deref_by_trait(
} }
Some(Canonical { Some(Canonical {
value: vars value: vars
.0
.value .value
.at(&Interner, vars.0.value.len(&Interner) - 1) .subst
.at(&Interner, vars.value.subst.len(&Interner) - 1)
.assert_ty_ref(&Interner) .assert_ty_ref(&Interner)
.clone(), .clone(),
binders: vars.0.binders.clone(), binders: vars.binders.clone(),
}) })
} }
Solution::Ambig(_) => { Solution::Ambig(_) => {

View file

@ -42,7 +42,7 @@ use super::{
}; };
use crate::{ use crate::{
db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 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. // 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()); self.db.trait_solve(self.resolver.krate().unwrap(), canonicalized.value.clone());
match solution { match solution {
Some(Solution::Unique(substs)) => { Some(Solution::Unique(canonical_subst)) => {
canonicalized.apply_solution(self, substs.0); canonicalized.apply_solution(
self,
Canonical {
binders: canonical_subst.binders,
// FIXME: handle constraints
value: canonical_subst.value.subst,
},
);
} }
Some(Solution::Ambig(Guidance::Definite(substs))) => { Some(Solution::Ambig(Guidance::Definite(substs))) => {
canonicalized.apply_solution(self, substs.0); canonicalized.apply_solution(self, substs);
self.obligations.push(obligation); self.obligations.push(obligation);
} }
Some(_) => { Some(_) => {

View file

@ -7,7 +7,7 @@
use chalk_ir::{cast::Cast, Mutability, TyVariableKind}; use chalk_ir::{cast::Cast, Mutability, TyVariableKind};
use hir_def::lang_item::LangItemTarget; 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}; use super::{InEnvironment, InferenceContext};
@ -148,7 +148,14 @@ impl<'a> InferenceContext<'a> {
match solution { match solution {
Solution::Unique(v) => { 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, _ => return None,
}; };

View file

@ -9,7 +9,7 @@ use stdx::panic_context;
use crate::{ use crate::{
db::HirDatabase, AliasEq, AliasTy, Canonical, DomainGoal, Guidance, HirDisplay, InEnvironment, 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}; use self::chalk::{from_chalk, Interner, ToChalk};
@ -173,23 +173,15 @@ fn solution_from_chalk(
db: &dyn HirDatabase, db: &dyn HirDatabase,
solution: chalk_solve::Solution<Interner>, solution: chalk_solve::Solution<Interner>,
) -> Solution { ) -> Solution {
let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<Interner>>| {
let result = from_chalk(db, subst);
SolutionVariables(result)
};
match solution { match solution {
chalk_solve::Solution::Unique(constr_subst) => { chalk_solve::Solution::Unique(constr_subst) => {
let subst = chalk_ir::Canonical { Solution::Unique(from_chalk(db, constr_subst))
value: constr_subst.value.subst,
binders: constr_subst.binders,
};
Solution::Unique(convert_subst(subst))
} }
chalk_solve::Solution::Ambig(chalk_solve::Guidance::Definite(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)) => { 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) => { chalk_solve::Solution::Ambig(chalk_solve::Guidance::Unknown) => {
Solution::Ambig(Guidance::Unknown) Solution::Ambig(Guidance::Unknown)

View file

@ -11,8 +11,8 @@ use hir_def::{GenericDefId, TypeAliasId};
use crate::{ use crate::{
chalk_ext::ProjectionTyExt, db::HirDatabase, static_lifetime, AliasTy, CallableDefId, chalk_ext::ProjectionTyExt, db::HirDatabase, static_lifetime, AliasTy, CallableDefId,
Canonical, DomainGoal, FnPointer, GenericArg, InEnvironment, OpaqueTy, ProjectionTy, Canonical, ConstrainedSubst, DomainGoal, FnPointer, GenericArg, InEnvironment, OpaqueTy,
QuantifiedWhereClause, Substitution, TraitRef, Ty, TypeWalk, WhereClause, ProjectionTy, QuantifiedWhereClause, Substitution, TraitRef, Ty, TypeWalk, WhereClause,
}; };
use super::interner::*; use super::interner::*;
@ -459,6 +459,18 @@ where
} }
} }
impl ToChalk for crate::ConstrainedSubst {
type Chalk = chalk_ir::ConstrainedSubst<Interner>;
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<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> pub(super) fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
where where
T: HasInterner<Interner = Interner>, T: HasInterner<Interner = Interner>,

View file

@ -490,14 +490,16 @@ pub struct AliasEq {
} }
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct SolutionVariables(pub Canonical<Substitution>); pub struct ConstrainedSubst {
pub subst: Substitution,
}
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
/// A (possible) solution for a proposed goal. /// A (possible) solution for a proposed goal.
pub enum Solution { pub enum Solution {
/// The goal indeed holds, and there is a unique value for all existential /// The goal indeed holds, and there is a unique value for all existential
/// variables. /// variables.
Unique(SolutionVariables), Unique(Canonical<ConstrainedSubst>),
/// The goal may be provable in multiple ways, but regardless we may have some guidance /// 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 /// 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 /// 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 /// ever to hold, but that alone isn't enough to guarantee the goal will
/// actually hold. /// actually hold.
Definite(SolutionVariables), Definite(Canonical<Substitution>),
/// There are multiple plausible values for the existentials, but the ones /// There are multiple plausible values for the existentials, but the ones
/// here are suggested as the preferred choice heuristically. These should /// here are suggested as the preferred choice heuristically. These should
/// be used for inference fallback only. /// be used for inference fallback only.
Suggested(SolutionVariables), Suggested(Canonical<Substitution>),
/// There's no useful information to feed back to type inference /// There's no useful information to feed back to type inference
Unknown, Unknown,