mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 12:29:21 +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,
|
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())),
|
||||||
|
|
|
@ -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(_) => {
|
||||||
|
|
|
@ -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(_) => {
|
||||||
|
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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>,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue