aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/traits.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/traits.rs')
-rw-r--r--crates/hir_ty/src/traits.rs38
1 files changed, 26 insertions, 12 deletions
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs
index e4cdb6d53..edfafdff8 100644
--- a/crates/hir_ty/src/traits.rs
+++ b/crates/hir_ty/src/traits.rs
@@ -10,7 +10,9 @@ use stdx::panic_context;
10 10
11use crate::{db::HirDatabase, DebruijnIndex, Substs}; 11use crate::{db::HirDatabase, DebruijnIndex, Substs};
12 12
13use super::{Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TypeWalk}; 13use super::{
14 Canonical, GenericPredicate, HirDisplay, ProjectionTy, TraitRef, Ty, TyKind, TypeWalk,
15};
14 16
15use self::chalk::{from_chalk, Interner, ToChalk}; 17use self::chalk::{from_chalk, Interner, ToChalk};
16 18
@@ -38,26 +40,38 @@ fn create_chalk_solver() -> chalk_recursive::RecursiveSolver<Interner> {
38/// fn foo<T: Default>(t: T) {} 40/// fn foo<T: Default>(t: T) {}
39/// ``` 41/// ```
40/// we assume that `T: Default`. 42/// we assume that `T: Default`.
41#[derive(Clone, Debug, PartialEq, Eq, Hash)] 43#[derive(Debug, Clone, PartialEq, Eq, Hash)]
42pub struct TraitEnvironment { 44pub struct TraitEnvironment {
43 pub predicates: Vec<GenericPredicate>, 45 // When we're using Chalk's Ty we can make this a BTreeMap since it's Ord,
46 // but for now it's too annoying...
47 pub(crate) traits_from_clauses: Vec<(Ty, TraitId)>,
48 pub(crate) env: chalk_ir::Environment<Interner>,
44} 49}
45 50
46impl TraitEnvironment { 51impl TraitEnvironment {
47 /// Returns trait refs with the given self type which are supposed to hold 52 pub(crate) fn traits_in_scope_from_clauses<'a>(
48 /// in this trait env. E.g. if we are in `foo<T: SomeTrait>()`, this will
49 /// find that `T: SomeTrait` if we call it for `T`.
50 pub(crate) fn trait_predicates_for_self_ty<'a>(
51 &'a self, 53 &'a self,
52 ty: &'a Ty, 54 ty: &'a Ty,
53 ) -> impl Iterator<Item = &'a TraitRef> + 'a { 55 ) -> impl Iterator<Item = TraitId> + 'a {
54 self.predicates.iter().filter_map(move |pred| match pred { 56 self.traits_from_clauses.iter().filter_map(move |(self_ty, trait_id)| {
55 GenericPredicate::Implemented(tr) if tr.self_ty() == ty => Some(tr), 57 if self_ty == ty {
56 _ => None, 58 Some(*trait_id)
59 } else {
60 None
61 }
57 }) 62 })
58 } 63 }
59} 64}
60 65
66impl Default for TraitEnvironment {
67 fn default() -> Self {
68 TraitEnvironment {
69 traits_from_clauses: Vec::new(),
70 env: chalk_ir::Environment::new(&Interner),
71 }
72 }
73}
74
61/// Something (usually a goal), along with an environment. 75/// Something (usually a goal), along with an environment.
62#[derive(Clone, Debug, PartialEq, Eq, Hash)] 76#[derive(Clone, Debug, PartialEq, Eq, Hash)]
63pub struct InEnvironment<T> { 77pub struct InEnvironment<T> {
@@ -129,7 +143,7 @@ pub(crate) fn trait_solve_query(
129 log::info!("trait_solve_query({})", goal.value.value.display(db)); 143 log::info!("trait_solve_query({})", goal.value.value.display(db));
130 144
131 if let Obligation::Projection(pred) = &goal.value.value { 145 if let Obligation::Projection(pred) = &goal.value.value {
132 if let Ty::BoundVar(_) = &pred.projection_ty.parameters[0] { 146 if let TyKind::BoundVar(_) = &pred.projection_ty.parameters[0].interned(&Interner) {
133 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible 147 // Hack: don't ask Chalk to normalize with an unknown self type, it'll say that's impossible
134 return Some(Solution::Ambig(Guidance::Unknown)); 148 return Some(Solution::Ambig(Guidance::Unknown));
135 } 149 }