diff options
Diffstat (limited to 'crates/hir_ty/src/autoderef.rs')
-rw-r--r-- | crates/hir_ty/src/autoderef.rs | 51 |
1 files changed, 30 insertions, 21 deletions
diff --git a/crates/hir_ty/src/autoderef.rs b/crates/hir_ty/src/autoderef.rs index 23ab042c1..dc5fc759a 100644 --- a/crates/hir_ty/src/autoderef.rs +++ b/crates/hir_ty/src/autoderef.rs | |||
@@ -16,8 +16,8 @@ use crate::{ | |||
16 | to_assoc_type_id, to_chalk_trait_id, | 16 | to_assoc_type_id, to_chalk_trait_id, |
17 | traits::{InEnvironment, Solution}, | 17 | traits::{InEnvironment, Solution}, |
18 | utils::generics, | 18 | utils::generics, |
19 | AliasEq, AliasTy, BoundVar, Canonical, DebruijnIndex, Interner, ProjectionTy, Substitution, | 19 | AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, Interner, |
20 | TraitRef, Ty, TyKind, | 20 | ProjectionTy, Substitution, TraitRef, Ty, TyKind, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | const AUTODEREF_RECURSION_LIMIT: usize = 10; | 23 | const AUTODEREF_RECURSION_LIMIT: usize = 10; |
@@ -27,9 +27,9 @@ pub fn autoderef<'a>( | |||
27 | krate: Option<CrateId>, | 27 | krate: Option<CrateId>, |
28 | ty: InEnvironment<Canonical<Ty>>, | 28 | ty: InEnvironment<Canonical<Ty>>, |
29 | ) -> impl Iterator<Item = Canonical<Ty>> + 'a { | 29 | ) -> impl Iterator<Item = Canonical<Ty>> + 'a { |
30 | let InEnvironment { value: ty, environment } = ty; | 30 | let InEnvironment { goal: ty, environment } = ty; |
31 | successors(Some(ty), move |ty| { | 31 | successors(Some(ty), move |ty| { |
32 | deref(db, krate?, InEnvironment { value: ty, environment: environment.clone() }) | 32 | deref(db, krate?, InEnvironment { goal: ty, environment: environment.clone() }) |
33 | }) | 33 | }) |
34 | .take(AUTODEREF_RECURSION_LIMIT) | 34 | .take(AUTODEREF_RECURSION_LIMIT) |
35 | } | 35 | } |
@@ -39,8 +39,8 @@ pub(crate) fn deref( | |||
39 | krate: CrateId, | 39 | krate: CrateId, |
40 | ty: InEnvironment<&Canonical<Ty>>, | 40 | ty: InEnvironment<&Canonical<Ty>>, |
41 | ) -> Option<Canonical<Ty>> { | 41 | ) -> Option<Canonical<Ty>> { |
42 | if let Some(derefed) = ty.value.value.builtin_deref() { | 42 | if let Some(derefed) = ty.goal.value.builtin_deref() { |
43 | Some(Canonical { value: derefed, kinds: ty.value.kinds.clone() }) | 43 | Some(Canonical { value: derefed, binders: ty.goal.binders.clone() }) |
44 | } else { | 44 | } else { |
45 | deref_by_trait(db, krate, ty) | 45 | deref_by_trait(db, krate, ty) |
46 | } | 46 | } |
@@ -67,15 +67,15 @@ fn deref_by_trait( | |||
67 | // FIXME make the Canonical / bound var handling nicer | 67 | // FIXME make the Canonical / bound var handling nicer |
68 | 68 | ||
69 | let parameters = | 69 | let parameters = |
70 | Substitution::build_for_generics(&generic_params).push(ty.value.value.clone()).build(); | 70 | Substitution::build_for_generics(&generic_params).push(ty.goal.value.clone()).build(); |
71 | 71 | ||
72 | // Check that the type implements Deref at all | 72 | // Check that the type implements Deref at all |
73 | let trait_ref = | 73 | let trait_ref = |
74 | TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() }; | 74 | TraitRef { trait_id: to_chalk_trait_id(deref_trait), substitution: parameters.clone() }; |
75 | let implements_goal = Canonical { | 75 | let implements_goal = Canonical { |
76 | kinds: ty.value.kinds.clone(), | 76 | binders: ty.goal.binders.clone(), |
77 | value: InEnvironment { | 77 | value: InEnvironment { |
78 | value: trait_ref.cast(&Interner), | 78 | goal: trait_ref.cast(&Interner), |
79 | environment: ty.environment.clone(), | 79 | environment: ty.environment.clone(), |
80 | }, | 80 | }, |
81 | }; | 81 | }; |
@@ -89,18 +89,27 @@ fn deref_by_trait( | |||
89 | associated_ty_id: to_assoc_type_id(target), | 89 | associated_ty_id: to_assoc_type_id(target), |
90 | substitution: parameters, | 90 | substitution: parameters, |
91 | }), | 91 | }), |
92 | ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, ty.value.kinds.len())) | 92 | ty: TyKind::BoundVar(BoundVar::new( |
93 | .intern(&Interner), | 93 | DebruijnIndex::INNERMOST, |
94 | ty.goal.binders.len(&Interner), | ||
95 | )) | ||
96 | .intern(&Interner), | ||
94 | }; | 97 | }; |
95 | 98 | ||
96 | let obligation = projection.cast(&Interner); | 99 | let obligation = projection.cast(&Interner); |
97 | 100 | ||
98 | let in_env = InEnvironment { value: obligation, environment: ty.environment }; | 101 | let in_env = InEnvironment { goal: obligation, environment: ty.environment }; |
99 | 102 | ||
100 | let canonical = Canonical::new( | 103 | let canonical = Canonical { |
101 | in_env, | 104 | value: in_env, |
102 | ty.value.kinds.iter().copied().chain(Some(chalk_ir::TyVariableKind::General)), | 105 | binders: CanonicalVarKinds::from_iter( |
103 | ); | 106 | &Interner, |
107 | ty.goal.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new( | ||
108 | chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), | ||
109 | chalk_ir::UniverseIndex::ROOT, | ||
110 | ))), | ||
111 | ), | ||
112 | }; | ||
104 | 113 | ||
105 | let solution = db.trait_solve(krate, canonical)?; | 114 | let solution = db.trait_solve(krate, canonical)?; |
106 | 115 | ||
@@ -121,21 +130,21 @@ fn deref_by_trait( | |||
121 | // assumptions will be broken. We would need to properly introduce | 130 | // assumptions will be broken. We would need to properly introduce |
122 | // new variables in that case | 131 | // new variables in that case |
123 | 132 | ||
124 | for i in 1..vars.0.kinds.len() { | 133 | for i in 1..vars.0.binders.len(&Interner) { |
125 | if vars.0.value[i - 1].interned(&Interner) | 134 | if vars.0.value[i - 1].interned(&Interner) |
126 | != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) | 135 | != &TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, i - 1)) |
127 | { | 136 | { |
128 | warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.value, solution); | 137 | warn!("complex solution for derefing {:?}: {:?}, ignoring", ty.goal, solution); |
129 | return None; | 138 | return None; |
130 | } | 139 | } |
131 | } | 140 | } |
132 | Some(Canonical { | 141 | Some(Canonical { |
133 | value: vars.0.value[vars.0.value.len() - 1].clone(), | 142 | value: vars.0.value[vars.0.value.len() - 1].clone(), |
134 | kinds: vars.0.kinds.clone(), | 143 | binders: vars.0.binders.clone(), |
135 | }) | 144 | }) |
136 | } | 145 | } |
137 | Solution::Ambig(_) => { | 146 | Solution::Ambig(_) => { |
138 | info!("Ambiguous solution for derefing {:?}: {:?}", ty.value, solution); | 147 | info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution); |
139 | None | 148 | None |
140 | } | 149 | } |
141 | } | 150 | } |