From 638100dc8bea69cc4093d15f1641ed39a8d27a43 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 29 Jun 2019 17:40:00 +0200 Subject: Refactor a bit & introduce Environment struct --- crates/ra_hir/src/ty/method_resolution.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir/src/ty/method_resolution.rs') diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 76ace66ea..770e1964e 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use arrayvec::ArrayVec; use rustc_hash::FxHashMap; -use super::{autoderef, Canonical, TraitRef}; +use super::{autoderef, Canonical, Environment, InEnvironment, TraitRef}; use crate::{ generics::HasGenericParams, impl_block::{ImplBlock, ImplId, ImplItem}, @@ -209,7 +209,8 @@ fn iterate_trait_method_candidates( let data = m.data(db); if name.map_or(true, |name| data.name() == name) && data.has_self_param() { if !known_implemented { - let trait_ref = canonical_trait_ref(db, t, ty.clone()); + let env = Arc::new(super::Environment); // FIXME add environment + let trait_ref = canonical_trait_ref(db, env, t, ty.clone()); if db.implements(krate, trait_ref).is_none() { continue 'traits; } @@ -279,9 +280,10 @@ impl Ty { /// for all other parameters, to query Chalk with it. fn canonical_trait_ref( db: &impl HirDatabase, + env: Arc, trait_: Trait, self_ty: Canonical, -) -> Canonical { +) -> Canonical> { let mut substs = Vec::new(); let generics = trait_.generic_params(db); let num_vars = self_ty.num_vars; @@ -296,6 +298,6 @@ fn canonical_trait_ref( ); Canonical { num_vars: substs.len() - 1 + self_ty.num_vars, - value: TraitRef { trait_, substs: substs.into() }, + value: InEnvironment::new(env, TraitRef { trait_, substs: substs.into() }), } } -- cgit v1.2.3 From b1b12072eddaf989fb08ed7a2e39ec2dbbb83dde Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 29 Jun 2019 19:14:52 +0200 Subject: Start handling environment in trait resolution I.e. if we are inside a function with some where clauses, we assume these where clauses hold. --- crates/ra_hir/src/ty/method_resolution.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir/src/ty/method_resolution.rs') diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 770e1964e..40f5eabf0 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -7,7 +7,7 @@ use std::sync::Arc; use arrayvec::ArrayVec; use rustc_hash::FxHashMap; -use super::{autoderef, Canonical, Environment, InEnvironment, TraitRef}; +use super::{autoderef, lower, Canonical, Environment, InEnvironment, TraitRef}; use crate::{ generics::HasGenericParams, impl_block::{ImplBlock, ImplId, ImplItem}, @@ -198,6 +198,8 @@ fn iterate_trait_method_candidates( mut callback: impl FnMut(&Ty, Function) -> Option, ) -> Option { let krate = resolver.krate()?; + // FIXME: maybe put the trait_env behind a query (need to figure out good input parameters for that) + let env = lower::trait_env(db, resolver); 'traits: for t in resolver.traits_in_scope(db) { let data = t.trait_data(db); // we'll be lazy about checking whether the type implements the @@ -209,8 +211,7 @@ fn iterate_trait_method_candidates( let data = m.data(db); if name.map_or(true, |name| data.name() == name) && data.has_self_param() { if !known_implemented { - let env = Arc::new(super::Environment); // FIXME add environment - let trait_ref = canonical_trait_ref(db, env, t, ty.clone()); + let trait_ref = canonical_trait_ref(db, env.clone(), t, ty.clone()); if db.implements(krate, trait_ref).is_none() { continue 'traits; } -- cgit v1.2.3 From 9afbf2dff43dee3227358f10162d4c77d192ce7a Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Mon, 8 Jul 2019 21:43:52 +0200 Subject: Unify `normalize` and `implements` to simplify code --- crates/ra_hir/src/ty/method_resolution.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'crates/ra_hir/src/ty/method_resolution.rs') diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 40f5eabf0..e214bf1af 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs @@ -211,8 +211,8 @@ fn iterate_trait_method_candidates( let data = m.data(db); if name.map_or(true, |name| data.name() == name) && data.has_self_param() { if !known_implemented { - let trait_ref = canonical_trait_ref(db, env.clone(), t, ty.clone()); - if db.implements(krate, trait_ref).is_none() { + let goal = generic_implements_goal(db, env.clone(), t, ty.clone()); + if db.solve(krate, goal).is_none() { continue 'traits; } } @@ -279,12 +279,12 @@ impl Ty { /// This creates Substs for a trait with the given Self type and type variables /// for all other parameters, to query Chalk with it. -fn canonical_trait_ref( +fn generic_implements_goal( db: &impl HirDatabase, env: Arc, trait_: Trait, self_ty: Canonical, -) -> Canonical> { +) -> Canonical> { let mut substs = Vec::new(); let generics = trait_.generic_params(db); let num_vars = self_ty.num_vars; @@ -297,8 +297,8 @@ fn canonical_trait_ref( .enumerate() .map(|(i, _p)| Ty::Bound((i + num_vars) as u32)), ); - Canonical { - num_vars: substs.len() - 1 + self_ty.num_vars, - value: InEnvironment::new(env, TraitRef { trait_, substs: substs.into() }), - } + let num_vars = substs.len() - 1 + self_ty.num_vars; + let trait_ref = TraitRef { trait_, substs: substs.into() }; + let obligation = super::Obligation::Trait(trait_ref); + Canonical { num_vars, value: InEnvironment::new(env, obligation) } } -- cgit v1.2.3