Turn implements into a query again

This commit is contained in:
Florian Diebold 2019-05-05 16:04:31 +02:00
parent ef782adc29
commit a78228a39c
5 changed files with 13 additions and 8 deletions

View File

@ -161,6 +161,13 @@ pub trait HirDatabase: DefDatabase {
#[salsa::invoke(crate::ty::traits::solver)]
#[salsa::volatile]
fn solver(&self, krate: Crate) -> Arc<Mutex<crate::ty::traits::Solver>>;
#[salsa::invoke(crate::ty::traits::implements)]
fn implements(
&self,
krate: Crate,
goal: crate::ty::Canonical<crate::ty::TraitRef>,
) -> Option<crate::ty::traits::Solution>;
}
#[test]

View File

@ -240,7 +240,7 @@ impl TraitRef {
/// many there are. This is used to erase irrelevant differences between types
/// before using them in queries.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub(crate) struct Canonical<T> {
pub struct Canonical<T> {
pub value: T,
pub num_vars: usize,
}

View File

@ -328,8 +328,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
Obligation::Trait(tr) => {
let canonicalized = self.canonicalizer().canonicalize_trait_ref(tr.clone());
(
super::traits::implements(
self.db,
self.db.implements(
self.resolver.krate().unwrap(),
canonicalized.value.clone(),
),

View File

@ -196,8 +196,7 @@ fn iterate_trait_method_candidates<T>(
if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() {
if !known_implemented {
let trait_ref = canonical_trait_ref(db, t, ty.clone());
// FIXME cache this implements check (without solution) in a query?
if super::traits::implements(db, krate, trait_ref).is_none() {
if db.implements(krate, trait_ref).is_none() {
continue 'traits;
}
}

View File

@ -125,11 +125,11 @@ fn solution_from_chalk(db: &impl HirDatabase, solution: chalk_solve::Solution) -
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct SolutionVariables(pub Canonical<Vec<Ty>>);
pub struct SolutionVariables(pub Canonical<Vec<Ty>>);
#[derive(Clone, Debug, PartialEq, Eq)]
/// A (possible) solution for a proposed goal.
pub(crate) enum Solution {
pub enum Solution {
/// The goal indeed holds, and there is a unique value for all existential
/// variables.
Unique(SolutionVariables),
@ -144,7 +144,7 @@ pub(crate) enum Solution {
#[derive(Clone, Debug, PartialEq, Eq)]
/// When a goal holds ambiguously (e.g., because there are multiple possible
/// solutions), we issue a set of *guidance* back to type inference.
pub(crate) enum Guidance {
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.