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, layout::Integer,
path::{ModPath, Path}, path::{ModPath, Path},
resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs}, resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
type_ref::TypeRef, type_ref::{LifetimeRef, TypeRef},
AdtId, AssocItemId, DefWithBodyId, FieldId, FunctionId, ItemContainerId, Lookup, TraitId, AdtId, AssocItemId, DefWithBodyId, FieldId, FunctionId, ItemContainerId, Lookup, TraitId,
TupleFieldId, TupleId, TypeAliasId, VariantId, TupleFieldId, TupleId, TypeAliasId, VariantId,
}; };
@ -1037,6 +1037,12 @@ impl<'a> InferenceContext<'a> {
self.result.standard_types.unknown.clone() 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. /// 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 { fn insert_type_vars_shallow(&mut self, ty: Ty) -> Ty {
self.table.insert_type_vars_shallow(ty) self.table.insert_type_vars_shallow(ty)

View file

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

View file

@ -16,12 +16,12 @@ use triomphe::Arc;
use super::{InferOk, InferResult, InferenceContext, TypeError}; use super::{InferOk, InferResult, InferenceContext, TypeError};
use crate::{ use crate::{
consteval::unknown_const, db::HirDatabase, fold_tys_and_consts, static_lifetime, consteval::unknown_const, db::HirDatabase, fold_generic_args, fold_tys_and_consts,
to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical, Const, ConstValue, static_lifetime, to_chalk_trait_id, traits::FnTrait, AliasEq, AliasTy, BoundVar, Canonical,
DebruijnIndex, DomainGoal, GenericArg, GenericArgData, Goal, GoalData, Guidance, InEnvironment, Const, ConstValue, DebruijnIndex, DomainGoal, GenericArg, GenericArgData, Goal, GoalData,
InferenceVar, Interner, Lifetime, OpaqueTyId, ParamKind, ProjectionTy, ProjectionTyExt, Scalar, Guidance, InEnvironment, InferenceVar, Interner, Lifetime, OpaqueTyId, ParamKind, ProjectionTy,
Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt, TyKind, VariableKind, ProjectionTyExt, Scalar, Solution, Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
WhereClause, TyKind, VariableKind, WhereClause,
}; };
impl InferenceContext<'_> { impl InferenceContext<'_> {
@ -862,11 +862,16 @@ impl<'a> InferenceTable<'a> {
where where
T: HasInterner<Interner = Interner> + TypeFoldable<Interner>, T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
{ {
fold_tys_and_consts( fold_generic_args(
ty, ty,
|it, _| match it { |arg, _| match arg {
Either::Left(ty) => Either::Left(self.insert_type_vars_shallow(ty)), GenericArgData::Ty(ty) => GenericArgData::Ty(self.insert_type_vars_shallow(ty)),
Either::Right(c) => Either::Right(self.insert_const_vars_shallow(c)), // 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, 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) 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 /// 'Canonicalizes' the `t` by replacing any errors with new variables. Also
/// ensures there are no unbound variables or inference variables anywhere in /// ensures there are no unbound variables or inference variables anywhere in
/// the `t`. /// the `t`.

View file

@ -1362,7 +1362,7 @@ impl<'a> TyLoweringContext<'a> {
ImplTrait { bounds: crate::make_single_type_binders(predicates) } 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) { match self.resolver.resolve_lifetime(lifetime) {
Some(resolution) => match resolution { Some(resolution) => match resolution {
LifetimeNs::Static => static_lifetime(), LifetimeNs::Static => static_lifetime(),