aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/ty/autoderef.rs27
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;
8use hir_def::{lang_item::LangItemTarget, resolver::Resolver}; 8use hir_def::{lang_item::LangItemTarget, resolver::Resolver};
9use hir_expand::name; 9use hir_expand::name;
10use log::{info, warn}; 10use log::{info, warn};
11use ra_db::CrateId;
11 12
12use crate::{db::HirDatabase, Trait}; 13use crate::{db::HirDatabase, Trait};
13 14
14use super::{traits::Solution, Canonical, Substs, Ty, TypeWalk}; 15use super::{
16 traits::{InEnvironment, Solution},
17 Canonical, Substs, Ty, TypeWalk,
18};
15 19
16const AUTODEREF_RECURSION_LIMIT: usize = 10; 20const 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
38fn deref_by_trait( 44fn 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 }