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 + TypeFoldable, { - 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 + TypeFold t.fold_with(&mut TyFolder(f), binders) } +pub(crate) fn fold_generic_args + TypeFoldable>( + 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 GenericArgData>(F); + impl GenericArgData> TypeFolder + for TyFolder + { + fn as_dyn(&mut self) -> &mut dyn TypeFolder { + 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(),