mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-16 09:48:10 +00:00
Remove SolutionVariables
, add ConstrainedSubst analogous to Chalk
... just missing the constraints.
This commit is contained in:
parent
31d2b3b9cb
commit
b03969cda9
7 changed files with 53 additions and 33 deletions
|
@ -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())),
|
||||
|
|
|
@ -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(_) => {
|
||||
|
|
|
@ -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(_) => {
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue