aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_ty/src/autoderef.rs
diff options
context:
space:
mode:
authorBenjamin Coenen <[email protected]>2020-04-17 09:30:39 +0100
committerBenjamin Coenen <[email protected]>2020-04-17 09:30:39 +0100
commit0a1585075c65dd6049fc11c641309c89210e222d (patch)
treeceda5ef63d2179f25a7d5abaa16fa1dc30c9867b /crates/ra_hir_ty/src/autoderef.rs
parent071ef268b5c8fb9afec1db912ebcc5d6577f5e73 (diff)
parent8d296be1090b21b60e509c831864ae85feec2490 (diff)
Merge branch 'master' of github.com:rust-analyzer/rust-analyzer
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 {