diff options
author | Florian Diebold <[email protected]> | 2020-04-10 16:44:43 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2020-04-16 12:06:23 +0100 |
commit | 14570df015d1641d1e382c9898e7c6d981b99e97 (patch) | |
tree | eb89057f63b5b85c029b2caa6a6cf22a834d67f4 /crates/ra_hir_ty/src/autoderef.rs | |
parent | 364415b7d66bc9d42f21181d7f642e9f911c4711 (diff) |
Switch Chalk to recursive solver
+ various fixes related to that.
Diffstat (limited to 'crates/ra_hir_ty/src/autoderef.rs')
-rw-r--r-- | crates/ra_hir_ty/src/autoderef.rs | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/crates/ra_hir_ty/src/autoderef.rs b/crates/ra_hir_ty/src/autoderef.rs index d91c21e24..1b0f84c5c 100644 --- a/crates/ra_hir_ty/src/autoderef.rs +++ b/crates/ra_hir_ty/src/autoderef.rs | |||
@@ -14,7 +14,7 @@ use crate::{ | |||
14 | db::HirDatabase, | 14 | db::HirDatabase, |
15 | traits::{InEnvironment, Solution}, | 15 | traits::{InEnvironment, Solution}, |
16 | utils::generics, | 16 | utils::generics, |
17 | BoundVar, Canonical, DebruijnIndex, Substs, Ty, | 17 | BoundVar, Canonical, DebruijnIndex, Obligation, Substs, TraitRef, Ty, |
18 | }; | 18 | }; |
19 | 19 | ||
20 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 20 | const AUTODEREF_RECURSION_LIMIT: usize = 10; |
@@ -66,6 +66,20 @@ fn deref_by_trait( | |||
66 | let parameters = | 66 | let parameters = |
67 | Substs::build_for_generics(&generic_params).push(ty.value.value.clone()).build(); | 67 | Substs::build_for_generics(&generic_params).push(ty.value.value.clone()).build(); |
68 | 68 | ||
69 | // Check that the type implements Deref at all | ||
70 | let trait_ref = TraitRef { trait_: deref_trait, substs: parameters.clone() }; | ||
71 | let implements_goal = super::Canonical { | ||
72 | num_vars: ty.value.num_vars, | ||
73 | value: InEnvironment { | ||
74 | value: Obligation::Trait(trait_ref), | ||
75 | environment: ty.environment.clone(), | ||
76 | }, | ||
77 | }; | ||
78 | if db.trait_solve(krate, implements_goal).is_none() { | ||
79 | return None; | ||
80 | } | ||
81 | |||
82 | // Now do the assoc type projection | ||
69 | let projection = super::traits::ProjectionPredicate { | 83 | let projection = super::traits::ProjectionPredicate { |
70 | ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.num_vars)), | 84 | ty: Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.num_vars)), |
71 | projection_ty: super::ProjectionTy { associated_ty: target, parameters }, | 85 | projection_ty: super::ProjectionTy { associated_ty: target, parameters }, |
@@ -91,6 +105,11 @@ fn deref_by_trait( | |||
91 | // they're just being 'passed through'. In the 'standard' case where | 105 | // they're just being 'passed through'. In the 'standard' case where |
92 | // we have `impl<T> Deref for Foo<T> { Target = T }`, that should be | 106 | // we have `impl<T> Deref for Foo<T> { Target = T }`, that should be |
93 | // the case. | 107 | // the case. |
108 | |||
109 | // FIXME: if the trait solver decides to truncate the type, these | ||
110 | // assumptions will be broken. We would need to properly introduce | ||
111 | // new variables in that case | ||
112 | |||
94 | for i in 1..vars.0.num_vars { | 113 | for i in 1..vars.0.num_vars { |
95 | if vars.0.value[i - 1] != Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) | 114 | if vars.0.value[i - 1] != Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) |
96 | { | 115 | { |