diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-09 08:50:18 +0100 |
---|---|---|
committer | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2019-07-09 08:50:18 +0100 |
commit | f59cd1a4a0d6c369025a7014e838d25f91d478e4 (patch) | |
tree | 2c4b9dc868a87507ed63e9dc46530cc60f38ae64 /crates/ra_hir/src/ty/infer | |
parent | 35f28c538a9b9f461bb4db1a78d02e9f02a3d296 (diff) | |
parent | 9afbf2dff43dee3227358f10162d4c77d192ce7a (diff) |
Merge #1515
1515: Trait environment r=matklad a=flodiebold
This adds the environment, i.e. the set of `where` clauses in scope, when solving trait goals. That means that e.g. in
```rust
fn foo<T: SomeTrait>(t: T) {}
```
, we are able to complete methods of `SomeTrait` on the `t`. This affects the trait APIs quite a bit (since every method that needs to be able to solve for some trait needs to get this environment somehow), so I thought I'd do it rather sooner than later ;)
Co-authored-by: Florian Diebold <[email protected]>
Diffstat (limited to 'crates/ra_hir/src/ty/infer')
-rw-r--r-- | crates/ra_hir/src/ty/infer/unify.rs | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/crates/ra_hir/src/ty/infer/unify.rs b/crates/ra_hir/src/ty/infer/unify.rs index a24e5eb5c..e7e8825d1 100644 --- a/crates/ra_hir/src/ty/infer/unify.rs +++ b/crates/ra_hir/src/ty/infer/unify.rs | |||
@@ -1,8 +1,10 @@ | |||
1 | //! Unification and canonicalization logic. | 1 | //! Unification and canonicalization logic. |
2 | 2 | ||
3 | use super::InferenceContext; | 3 | use super::{InferenceContext, Obligation}; |
4 | use crate::db::HirDatabase; | 4 | use crate::db::HirDatabase; |
5 | use crate::ty::{Canonical, InferTy, ProjectionPredicate, ProjectionTy, TraitRef, Ty}; | 5 | use crate::ty::{ |
6 | Canonical, InEnvironment, InferTy, ProjectionPredicate, ProjectionTy, TraitRef, Ty, | ||
7 | }; | ||
6 | 8 | ||
7 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { | 9 | impl<'a, D: HirDatabase> InferenceContext<'a, D> { |
8 | pub(super) fn canonicalizer<'b>(&'b mut self) -> Canonicalizer<'a, 'b, D> | 10 | pub(super) fn canonicalizer<'b>(&'b mut self) -> Canonicalizer<'a, 'b, D> |
@@ -105,22 +107,28 @@ where | |||
105 | ProjectionPredicate { ty, projection_ty } | 107 | ProjectionPredicate { ty, projection_ty } |
106 | } | 108 | } |
107 | 109 | ||
108 | pub fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> { | 110 | // FIXME: add some point, we need to introduce a `Fold` trait that abstracts |
109 | let result = self.do_canonicalize_ty(ty); | 111 | // over all the things that can be canonicalized (like Chalk and rustc have) |
110 | self.into_canonicalized(result) | ||
111 | } | ||
112 | 112 | ||
113 | pub fn canonicalize_trait_ref(mut self, trait_ref: TraitRef) -> Canonicalized<TraitRef> { | 113 | pub(crate) fn canonicalize_ty(mut self, ty: Ty) -> Canonicalized<Ty> { |
114 | let result = self.do_canonicalize_trait_ref(trait_ref); | 114 | let result = self.do_canonicalize_ty(ty); |
115 | self.into_canonicalized(result) | 115 | self.into_canonicalized(result) |
116 | } | 116 | } |
117 | 117 | ||
118 | pub fn canonicalize_projection( | 118 | pub(crate) fn canonicalize_obligation( |
119 | mut self, | 119 | mut self, |
120 | projection: ProjectionPredicate, | 120 | obligation: InEnvironment<Obligation>, |
121 | ) -> Canonicalized<ProjectionPredicate> { | 121 | ) -> Canonicalized<InEnvironment<Obligation>> { |
122 | let result = self.do_canonicalize_projection_predicate(projection); | 122 | let result = match obligation.value { |
123 | self.into_canonicalized(result) | 123 | Obligation::Trait(tr) => Obligation::Trait(self.do_canonicalize_trait_ref(tr)), |
124 | Obligation::Projection(pr) => { | ||
125 | Obligation::Projection(self.do_canonicalize_projection_predicate(pr)) | ||
126 | } | ||
127 | }; | ||
128 | self.into_canonicalized(InEnvironment { | ||
129 | value: result, | ||
130 | environment: obligation.environment, | ||
131 | }) | ||
124 | } | 132 | } |
125 | } | 133 | } |
126 | 134 | ||