aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/autoderef.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_ty/src/autoderef.rs')
-rw-r--r--crates/ra_hir_ty/src/autoderef.rs21
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
20const AUTODEREF_RECURSION_LIMIT: usize = 10; 20const 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 {