Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir-ty/src/infer.rs8
-rw-r--r--crates/hir-ty/src/infer/expr.rs3
-rw-r--r--crates/hir-ty/src/infer/unify.rs25
-rw-r--r--crates/hir-ty/src/lib.rs49
-rw-r--r--crates/hir-ty/src/lower.rs2
5 files changed, 73 insertions, 14 deletions
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 29e1279945..be3b50e141 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -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)
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index aab052fdf1..35d5967935 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -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);
}
diff --git a/crates/hir-ty/src/infer/unify.rs b/crates/hir-ty/src/infer/unify.rs
index a6c5666911..afb89fe1e5 100644
--- a/crates/hir-ty/src/infer/unify.rs
+++ b/crates/hir-ty/src/infer/unify.rs
@@ -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,
)
diff --git a/crates/hir-ty/src/lib.rs b/crates/hir-ty/src/lib.rs
index fc7ed79f5c..e217cf3d09 100644
--- a/crates/hir-ty/src/lib.rs
+++ b/crates/hir-ty/src/lib.rs
@@ -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`.
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index b4ff98a63c..d0d30fd570 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -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(),