|
6 | 6 | use std::iter::successors;
|
7 | 7 |
|
8 | 8 | use base_db::CrateId;
|
9 |
| -use chalk_ir::cast::Cast; |
| 9 | +use chalk_ir::{cast::Cast, fold::Fold, interner::HasInterner, VariableKind}; |
10 | 10 | use hir_def::lang_item::LangItemTarget;
|
11 | 11 | use hir_expand::name::name;
|
12 | 12 | use log::{info, warn};
|
13 | 13 |
|
14 | 14 | use crate::{
|
15 |
| - db::HirDatabase, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, DebruijnIndex, |
16 |
| - InEnvironment, Interner, ProjectionTyExt, Solution, Ty, TyBuilder, TyKind, |
| 15 | + db::HirDatabase, static_lifetime, AliasEq, AliasTy, BoundVar, Canonical, CanonicalVarKinds, |
| 16 | + DebruijnIndex, InEnvironment, Interner, ProjectionTyExt, Solution, Substitution, Ty, TyBuilder, |
| 17 | + TyKind, |
17 | 18 | };
|
18 | 19 |
|
19 | 20 | const AUTODEREF_RECURSION_LIMIT: usize = 10;
|
@@ -103,7 +104,7 @@ fn deref_by_trait(
|
103 | 104 | binders: CanonicalVarKinds::from_iter(
|
104 | 105 | &Interner,
|
105 | 106 | ty.goal.binders.iter(&Interner).cloned().chain(Some(chalk_ir::WithKind::new(
|
106 |
| - chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), |
| 107 | + VariableKind::Ty(chalk_ir::TyVariableKind::General), |
107 | 108 | chalk_ir::UniverseIndex::ROOT,
|
108 | 109 | ))),
|
109 | 110 | ),
|
@@ -136,19 +137,50 @@ fn deref_by_trait(
|
136 | 137 | return None;
|
137 | 138 | }
|
138 | 139 | }
|
139 |
| - Some(Canonical { |
| 140 | + // FIXME: we remove lifetime variables here since they can confuse |
| 141 | + // the method resolution code later |
| 142 | + Some(fixup_lifetime_variables(Canonical { |
140 | 143 | value: vars
|
141 | 144 | .value
|
142 | 145 | .subst
|
143 | 146 | .at(&Interner, vars.value.subst.len(&Interner) - 1)
|
144 | 147 | .assert_ty_ref(&Interner)
|
145 | 148 | .clone(),
|
146 | 149 | binders: vars.binders.clone(),
|
147 |
| - }) |
| 150 | + })) |
148 | 151 | }
|
149 | 152 | Solution::Ambig(_) => {
|
150 | 153 | info!("Ambiguous solution for derefing {:?}: {:?}", ty.goal, solution);
|
151 | 154 | None
|
152 | 155 | }
|
153 | 156 | }
|
154 | 157 | }
|
| 158 | + |
| 159 | +fn fixup_lifetime_variables<T: Fold<Interner, Result = T> + HasInterner<Interner = Interner>>( |
| 160 | + c: Canonical<T>, |
| 161 | +) -> Canonical<T> { |
| 162 | + // Removes lifetime variables from the Canonical, replacing them by static lifetimes. |
| 163 | + let mut i = 0; |
| 164 | + let subst = Substitution::from_iter( |
| 165 | + &Interner, |
| 166 | + c.binders.iter(&Interner).map(|vk| match vk.kind { |
| 167 | + VariableKind::Ty(_) => { |
| 168 | + let index = i; |
| 169 | + i += 1; |
| 170 | + BoundVar::new(DebruijnIndex::INNERMOST, index).to_ty(&Interner).cast(&Interner) |
| 171 | + } |
| 172 | + VariableKind::Lifetime => static_lifetime().cast(&Interner), |
| 173 | + VariableKind::Const(_) => unimplemented!(), |
| 174 | + }), |
| 175 | + ); |
| 176 | + let binders = CanonicalVarKinds::from_iter( |
| 177 | + &Interner, |
| 178 | + c.binders.iter(&Interner).filter(|vk| match vk.kind { |
| 179 | + VariableKind::Ty(_) => true, |
| 180 | + VariableKind::Lifetime => false, |
| 181 | + VariableKind::Const(_) => true, |
| 182 | + }), |
| 183 | + ); |
| 184 | + let value = subst.apply(c.value, &Interner); |
| 185 | + Canonical { binders, value } |
| 186 | +} |
0 commit comments