mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 04:44:57 +00:00
Auto merge of #13223 - lowr:fix/hir-proj-normalization, r=flodiebold
fix: handle lifetime variables in projection normalization
Fixes #12674
The problem is that we've been skipping the binders of normalized projections assuming they should be empty, but the assumption is unfortunately wrong. We may get back lifetime variables and should handle them before returning them as normalized projections. For those who are curious why we get those even though we treat all lifetimes as 'static, [this comment in chalk](d875af0ff1/chalk-solve/src/infer/unify.rs (L888-L908)
) may be interesting.
I thought using `InferenceTable` would be cleaner than the other ways as it already has the methods for canonicalization, normalizing projection, and resolving variables, so moved goal building and trait solving logic to a new `HirDatabase` query. I made it transparent query as the query itself doesn't do much work but the eventual call to `HirDatabase::trait_solve_query()` does.
This commit is contained in:
commit
b1a4ba3e84
5 changed files with 94 additions and 42 deletions
|
@ -63,10 +63,9 @@ use hir_ty::{
|
|||
primitive::UintTy,
|
||||
subst_prefix,
|
||||
traits::FnTrait,
|
||||
AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast,
|
||||
ClosureId, DebruijnIndex, GenericArgData, InEnvironment, Interner, ParamKind,
|
||||
QuantifiedWhereClause, Scalar, Solution, Substitution, TraitEnvironment, TraitRefExt, Ty,
|
||||
TyBuilder, TyDefId, TyExt, TyKind, TyVariableKind, WhereClause,
|
||||
AliasTy, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId,
|
||||
GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar, Substitution,
|
||||
TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, WhereClause,
|
||||
};
|
||||
use itertools::Itertools;
|
||||
use nameres::diagnostics::DefDiagnosticKind;
|
||||
|
@ -2892,28 +2891,8 @@ impl Type {
|
|||
}
|
||||
})
|
||||
.build();
|
||||
let goal = hir_ty::make_canonical(
|
||||
InEnvironment::new(
|
||||
&self.env.env,
|
||||
AliasEq {
|
||||
alias: AliasTy::Projection(projection),
|
||||
ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
|
||||
.intern(Interner),
|
||||
}
|
||||
.cast(Interner),
|
||||
),
|
||||
[TyVariableKind::General].into_iter(),
|
||||
);
|
||||
|
||||
match db.trait_solve(self.env.krate, goal)? {
|
||||
Solution::Unique(s) => s
|
||||
.value
|
||||
.subst
|
||||
.as_slice(Interner)
|
||||
.first()
|
||||
.map(|ty| self.derived(ty.assert_ty_ref(Interner).clone())),
|
||||
Solution::Ambig(_) => None,
|
||||
}
|
||||
db.normalize_projection(projection, self.env.clone()).map(|ty| self.derived(ty))
|
||||
}
|
||||
|
||||
pub fn is_copy(&self, db: &dyn HirDatabase) -> bool {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue