modify insert_type_vars for lifetimes

This commit is contained in:
dfireBird 2024-03-19 10:14:45 +05:30
parent 13301e7a1a
commit b357bcab2b
No known key found for this signature in database
GPG key ID: 26D522CA5FC2B93D
5 changed files with 73 additions and 14 deletions

View file

@ -42,7 +42,7 @@ use hir_def::{
layout::Integer,
path::{ModPath, Path},
resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
type_ref::TypeRef,
type_ref::{LifetimeRef, TypeRef},
AdtId, AssocItemId, DefWithBodyId, FieldId, FunctionId, ItemContainerId, Lookup, TraitId,
TupleFieldId, TupleId, TypeAliasId, VariantId,
};
@ -1037,6 +1037,12 @@ impl<'a> InferenceContext<'a> {
self.result.standard_types.unknown.clone()
}
fn make_lifetime(&mut self, lifetime_ref: &LifetimeRef) -> Lifetime {
let ctx = crate::lower::TyLoweringContext::new(self.db, &self.resolver, self.owner.into());
let lt = ctx.lower_lifetime(lifetime_ref);
self.insert_type_vars(lt)
}
/// Replaces `Ty::Error` by a new type var, so we can maybe still infer it.
fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
self.table.insert_type_vars_shallow(ty)

View file

@ -1855,8 +1855,7 @@ impl InferenceContext<'_> {
DebruijnIndex::INNERMOST,
)
},
// FIXME: create make_lifetimes and infer lifetimes
|_, _| static_lifetime(),
|this, lt_ref| this.make_lifetime(lt_ref),
) {
substs.push(g);
}

View file

@ -16,12 +16,12 @@ use triomphe::Arc;
use super::{InferOk, InferResult, InferenceContext, TypeError};
use crate::{
consteval::unknown_const, db::HirDatabase, fold_tys_and_consts, static_lifetime,
to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical, Const, ConstValue,
DebruijnIndex, DomainGoal, GenericArg, GenericArgData, Goal, GoalData, Guidance, InEnvironment,
InferenceVar, Interner, Lifetime, OpaqueTyId, ParamKind, ProjectionTy, ProjectionTyExt, Scalar,
Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind, VariableKind,
WhereClause,
consteval::unknown_const, db::HirDatabase, fold_generic_args, fold_tys_and_consts,
static_lifetime, to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical,
Const, ConstValue, DebruijnIndex, DomainGoal, GenericArg, GenericArgData, Goal, GoalData,
Guidance, InEnvironment, InferenceVar, Interner, Lifetime, OpaqueTyId, ParamKind, ProjectionTy,
ProjectionTyExt, Scalar, Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
TyKind, VariableKind, WhereClause,
};
impl InferenceContext<'_> {
@ -862,11 +862,16 @@ impl<'a> InferenceTable<'a> {
where
T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
{
fold_tys_and_consts(
fold_generic_args(
ty,
|it, _| match it {
Either::Left(ty) => Either::Left(self.insert_type_vars_shallow(ty)),
Either::Right(c) => Either::Right(self.insert_const_vars_shallow(c)),
|arg, _| match arg {
GenericArgData::Ty(ty) => GenericArgData::Ty(self.insert_type_vars_shallow(ty)),
// FIXME: insert lifetime vars once LifetimeData::InferenceVar
// and specific error variant for lifetimes start being constructed
GenericArgData::Lifetime(lt) => GenericArgData::Lifetime(lt),
GenericArgData::Const(c) => {
GenericArgData::Const(self.insert_const_vars_shallow(c))
}
},
DebruijnIndex::INNERMOST,
)

View file

@ -716,6 +716,55 @@ pub(crate) fn fold_tys_and_consts<T: HasInterner<Interner = Interner> + TypeFold
t.fold_with(&mut TyFolder(f), binders)
}
pub(crate) fn fold_generic_args<T: HasInterner<Interner = Interner> + TypeFoldable<Interner>>(
t: T,
f: impl FnMut(GenericArgData, DebruijnIndex) -> GenericArgData,
binders: DebruijnIndex,
) -> T {
use chalk_ir::fold::{TypeFolder, TypeSuperFoldable};
#[derive(chalk_derive::FallibleTypeFolder)]
#[has_interner(Interner)]
struct TyFolder<F: FnMut(GenericArgData, DebruijnIndex) -> GenericArgData>(F);
impl<F: FnMut(GenericArgData, DebruijnIndex) -> GenericArgData> TypeFolder<Interner>
for TyFolder<F>
{
fn as_dyn(&mut self) -> &mut dyn TypeFolder<Interner> {
self
}
fn interner(&self) -> Interner {
Interner
}
fn fold_ty(&mut self, ty: Ty, outer_binder: DebruijnIndex) -> Ty {
let ty = ty.super_fold_with(self.as_dyn(), outer_binder);
self.0(GenericArgData::Ty(ty), outer_binder)
.intern(Interner)
.ty(Interner)
.unwrap()
.clone()
}
fn fold_const(&mut self, c: Const, outer_binder: DebruijnIndex) -> Const {
self.0(GenericArgData::Const(c), outer_binder)
.intern(Interner)
.constant(Interner)
.unwrap()
.clone()
}
fn fold_lifetime(&mut self, lt: Lifetime, outer_binder: DebruijnIndex) -> Lifetime {
let lt = lt.super_fold_with(self.as_dyn(), outer_binder);
self.0(GenericArgData::Lifetime(lt), outer_binder)
.intern(Interner)
.lifetime(Interner)
.unwrap()
.clone()
}
}
t.fold_with(&mut TyFolder(f), binders)
}
/// 'Canonicalizes' the `t` by replacing any errors with new variables. Also
/// ensures there are no unbound variables or inference variables anywhere in
/// the `t`.

View file

@ -1362,7 +1362,7 @@ impl<'a> TyLoweringContext<'a> {
ImplTrait { bounds: crate::make_single_type_binders(predicates) }
}
fn lower_lifetime(&self, lifetime: &LifetimeRef) -> Lifetime {
pub fn lower_lifetime(&self, lifetime: &LifetimeRef) -> Lifetime {
match self.resolver.resolve_lifetime(lifetime) {
Some(resolution) => match resolution {
LifetimeNs::Static => static_lifetime(),