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.rs | |
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.rs')
-rw-r--r-- | crates/ra_hir/src/ty/infer.rs | 69 |
1 files changed, 23 insertions, 46 deletions
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index 827addddd..26ddf0317 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -27,9 +27,10 @@ use ra_prof::profile; | |||
27 | use test_utils::tested_by; | 27 | use test_utils::tested_by; |
28 | 28 | ||
29 | use super::{ | 29 | use super::{ |
30 | autoderef, method_resolution, op, primitive, | 30 | autoderef, lower, method_resolution, op, primitive, |
31 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, | 31 | traits::{Guidance, Obligation, ProjectionPredicate, Solution}, |
32 | ApplicationTy, CallableDef, ProjectionTy, Substs, TraitRef, Ty, TypableDef, TypeCtor, | 32 | ApplicationTy, CallableDef, Environment, InEnvironment, ProjectionTy, Substs, TraitRef, Ty, |
33 | TypableDef, TypeCtor, | ||
33 | }; | 34 | }; |
34 | use crate::{ | 35 | use crate::{ |
35 | adt::VariantDef, | 36 | adt::VariantDef, |
@@ -165,6 +166,7 @@ struct InferenceContext<'a, D: HirDatabase> { | |||
165 | body: Arc<Body>, | 166 | body: Arc<Body>, |
166 | resolver: Resolver, | 167 | resolver: Resolver, |
167 | var_unification_table: InPlaceUnificationTable<TypeVarId>, | 168 | var_unification_table: InPlaceUnificationTable<TypeVarId>, |
169 | trait_env: Arc<Environment>, | ||
168 | obligations: Vec<Obligation>, | 170 | obligations: Vec<Obligation>, |
169 | method_resolutions: FxHashMap<ExprId, Function>, | 171 | method_resolutions: FxHashMap<ExprId, Function>, |
170 | field_resolutions: FxHashMap<ExprId, StructField>, | 172 | field_resolutions: FxHashMap<ExprId, StructField>, |
@@ -188,6 +190,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
188 | var_unification_table: InPlaceUnificationTable::new(), | 190 | var_unification_table: InPlaceUnificationTable::new(), |
189 | obligations: Vec::default(), | 191 | obligations: Vec::default(), |
190 | return_ty: Ty::Unknown, // set in collect_fn_signature | 192 | return_ty: Ty::Unknown, // set in collect_fn_signature |
193 | trait_env: lower::trait_env(db, &resolver), | ||
191 | db, | 194 | db, |
192 | body, | 195 | body, |
193 | resolver, | 196 | resolver, |
@@ -328,51 +331,25 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
328 | fn resolve_obligations_as_possible(&mut self) { | 331 | fn resolve_obligations_as_possible(&mut self) { |
329 | let obligations = mem::replace(&mut self.obligations, Vec::new()); | 332 | let obligations = mem::replace(&mut self.obligations, Vec::new()); |
330 | for obligation in obligations { | 333 | for obligation in obligations { |
331 | match &obligation { | 334 | let in_env = InEnvironment::new(self.trait_env.clone(), obligation.clone()); |
332 | Obligation::Trait(tr) => { | 335 | let canonicalized = self.canonicalizer().canonicalize_obligation(in_env); |
333 | let canonicalized = self.canonicalizer().canonicalize_trait_ref(tr.clone()); | 336 | let solution = |
334 | let solution = self | 337 | self.db.solve(self.resolver.krate().unwrap(), canonicalized.value.clone()); |
335 | .db | 338 | |
336 | .implements(self.resolver.krate().unwrap(), canonicalized.value.clone()); | 339 | match solution { |
337 | match solution { | 340 | Some(Solution::Unique(substs)) => { |
338 | Some(Solution::Unique(substs)) => { | 341 | canonicalized.apply_solution(self, substs.0); |
339 | canonicalized.apply_solution(self, substs.0); | ||
340 | } | ||
341 | Some(Solution::Ambig(Guidance::Definite(substs))) => { | ||
342 | canonicalized.apply_solution(self, substs.0); | ||
343 | self.obligations.push(obligation); | ||
344 | } | ||
345 | Some(_) => { | ||
346 | // FIXME use this when trying to resolve everything at the end | ||
347 | self.obligations.push(obligation); | ||
348 | } | ||
349 | None => { | ||
350 | // FIXME obligation cannot be fulfilled => diagnostic | ||
351 | } | ||
352 | }; | ||
353 | } | 342 | } |
354 | Obligation::Projection(pr) => { | 343 | Some(Solution::Ambig(Guidance::Definite(substs))) => { |
355 | let canonicalized = self.canonicalizer().canonicalize_projection(pr.clone()); | 344 | canonicalized.apply_solution(self, substs.0); |
356 | let solution = self | 345 | self.obligations.push(obligation); |
357 | .db | 346 | } |
358 | .normalize(self.resolver.krate().unwrap(), canonicalized.value.clone()); | 347 | Some(_) => { |
359 | 348 | // FIXME use this when trying to resolve everything at the end | |
360 | match solution { | 349 | self.obligations.push(obligation); |
361 | Some(Solution::Unique(substs)) => { | 350 | } |
362 | canonicalized.apply_solution(self, substs.0); | 351 | None => { |
363 | } | 352 | // FIXME obligation cannot be fulfilled => diagnostic |
364 | Some(Solution::Ambig(Guidance::Definite(substs))) => { | ||
365 | canonicalized.apply_solution(self, substs.0); | ||
366 | self.obligations.push(obligation); | ||
367 | } | ||
368 | Some(_) => { | ||
369 | // FIXME use this when trying to resolve everything at the end | ||
370 | self.obligations.push(obligation); | ||
371 | } | ||
372 | None => { | ||
373 | // FIXME obligation cannot be fulfilled => diagnostic | ||
374 | } | ||
375 | }; | ||
376 | } | 353 | } |
377 | }; | 354 | }; |
378 | } | 355 | } |