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,
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())),

View file

@ -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(_) => {

View file

@ -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(_) => {

View file

@ -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,
};

View file

@ -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<Interner>,
) -> Solution {
let convert_subst = |subst: chalk_ir::Canonical<chalk_ir::Substitution<Interner>>| {
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)

View file

@ -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<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>
where
T: HasInterner<Interner = Interner>,

View file

@ -490,14 +490,16 @@ pub struct AliasEq {
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SolutionVariables(pub Canonical<Substitution>);
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<ConstrainedSubst>),
/// 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<Substitution>),
/// 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<Substitution>),
/// There's no useful information to feed back to type inference
Unknown,