diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/ty/autoderef.rs | 27 |
1 files changed, 15 insertions, 12 deletions
diff --git a/crates/ra_hir/src/ty/autoderef.rs b/crates/ra_hir/src/ty/autoderef.rs index 41c99d227..86b08ae6f 100644 --- a/crates/ra_hir/src/ty/autoderef.rs +++ b/crates/ra_hir/src/ty/autoderef.rs | |||
@@ -8,10 +8,14 @@ use std::iter::successors; | |||
8 | use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; | 8 | use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; |
9 | use hir_expand::name; | 9 | use hir_expand::name; |
10 | use log::{info, warn}; | 10 | use log::{info, warn}; |
11 | use ra_db::CrateId; | ||
11 | 12 | ||
12 | use crate::{db::HirDatabase, Trait}; | 13 | use crate::{db::HirDatabase, Trait}; |
13 | 14 | ||
14 | use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; | 15 | use super::{ |
16 | traits::{InEnvironment, Solution}, | ||
17 | Canonical, Substs, Ty, TypeWalk, | ||
18 | }; | ||
15 | 19 | ||
16 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 20 | const AUTODEREF_RECURSION_LIMIT: usize = 10; |
17 | 21 | ||
@@ -31,16 +35,17 @@ pub(crate) fn deref( | |||
31 | if let Some(derefed) = ty.value.builtin_deref() { | 35 | if let Some(derefed) = ty.value.builtin_deref() { |
32 | Some(Canonical { value: derefed, num_vars: ty.num_vars }) | 36 | Some(Canonical { value: derefed, num_vars: ty.num_vars }) |
33 | } else { | 37 | } else { |
34 | deref_by_trait(db, resolver, ty) | 38 | let krate = resolver.krate()?; |
39 | let environment = super::lower::trait_env(db, resolver); | ||
40 | deref_by_trait(db, krate, InEnvironment { value: ty, environment }) | ||
35 | } | 41 | } |
36 | } | 42 | } |
37 | 43 | ||
38 | fn deref_by_trait( | 44 | fn deref_by_trait( |
39 | db: &impl HirDatabase, | 45 | db: &impl HirDatabase, |
40 | resolver: &Resolver, | 46 | krate: CrateId, |
41 | ty: &Canonical<Ty>, | 47 | ty: InEnvironment<&Canonical<Ty>>, |
42 | ) -> Option<Canonical<Ty>> { | 48 | ) -> Option<Canonical<Ty>> { |
43 | let krate = resolver.krate()?; | ||
44 | let deref_trait = match db.lang_item(krate.into(), "deref".into())? { | 49 | let deref_trait = match db.lang_item(krate.into(), "deref".into())? { |
45 | LangItemTarget::TraitId(t) => Trait::from(t), | 50 | LangItemTarget::TraitId(t) => Trait::from(t), |
46 | _ => return None, | 51 | _ => return None, |
@@ -56,10 +61,8 @@ fn deref_by_trait( | |||
56 | 61 | ||
57 | // FIXME make the Canonical handling nicer | 62 | // FIXME make the Canonical handling nicer |
58 | 63 | ||
59 | let env = super::lower::trait_env(db, resolver); | ||
60 | |||
61 | let parameters = Substs::build_for_generics(&generic_params) | 64 | let parameters = Substs::build_for_generics(&generic_params) |
62 | .push(ty.value.clone().shift_bound_vars(1)) | 65 | .push(ty.value.value.clone().shift_bound_vars(1)) |
63 | .build(); | 66 | .build(); |
64 | 67 | ||
65 | let projection = super::traits::ProjectionPredicate { | 68 | let projection = super::traits::ProjectionPredicate { |
@@ -69,9 +72,9 @@ fn deref_by_trait( | |||
69 | 72 | ||
70 | let obligation = super::Obligation::Projection(projection); | 73 | let obligation = super::Obligation::Projection(projection); |
71 | 74 | ||
72 | let in_env = super::traits::InEnvironment { value: obligation, environment: env }; | 75 | let in_env = InEnvironment { value: obligation, environment: ty.environment }; |
73 | 76 | ||
74 | let canonical = super::Canonical { num_vars: 1 + ty.num_vars, value: in_env }; | 77 | let canonical = super::Canonical { num_vars: 1 + ty.value.num_vars, value: in_env }; |
75 | 78 | ||
76 | let solution = db.trait_solve(krate.into(), canonical)?; | 79 | let solution = db.trait_solve(krate.into(), canonical)?; |
77 | 80 | ||
@@ -89,14 +92,14 @@ fn deref_by_trait( | |||
89 | // the case. | 92 | // the case. |
90 | for i in 1..vars.0.num_vars { | 93 | for i in 1..vars.0.num_vars { |
91 | if vars.0.value[i] != Ty::Bound((i - 1) as u32) { | 94 | if vars.0.value[i] != Ty::Bound((i - 1) as u32) { |
92 | warn!("complex solution for derefing {:?}: {:?}, ignoring", ty, solution); | 95 | warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); |
93 | return None; | 96 | return None; |
94 | } | 97 | } |
95 | } | 98 | } |
96 | Some(Canonical { value: vars.0.value[0].clone(), num_vars: vars.0.num_vars }) | 99 | Some(Canonical { value: vars.0.value[0].clone(), num_vars: vars.0.num_vars }) |
97 | } | 100 | } |
98 | Solution::Ambig(_) => { | 101 | Solution::Ambig(_) => { |
99 | info!("Ambiguous solution for derefing {:?}: {:?}", ty, solution); | 102 | info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution); |
100 | None | 103 | None |
101 | } | 104 | } |
102 | } | 105 | } |