diff options
| author | dfireBird <me@dfirebird.dev> | 2024-03-19 10:14:45 +0530 |
|---|---|---|
| committer | dfireBird <me@dfirebird.dev> | 2024-03-19 10:14:45 +0530 |
| commit | b357bcab2beb3533d3059b4c8723e4729a4333e2 (patch) | |
| tree | c69eed0abbcde25c655bf512b84439adc2a585b6 | |
| parent | 13301e7a1ae26214a038a6c344df9d85b895b540 (diff) | |
| download | rust-b357bcab2beb3533d3059b4c8723e4729a4333e2.tar.gz rust-b357bcab2beb3533d3059b4c8723e4729a4333e2.zip | |
modify `insert_type_vars` for lifetimes
| -rw-r--r-- | crates/hir-ty/src/infer.rs | 8 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/expr.rs | 3 | ||||
| -rw-r--r-- | crates/hir-ty/src/infer/unify.rs | 25 | ||||
| -rw-r--r-- | crates/hir-ty/src/lib.rs | 49 | ||||
| -rw-r--r-- | crates/hir-ty/src/lower.rs | 2 |
5 files changed, 73 insertions, 14 deletions
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 29e12799451..be3b50e1411 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 aab052fdf16..35d59679355 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 a6c5666911a..afb89fe1e5b 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 fc7ed79f5cf..e217cf3d09d 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 b4ff98a63c6..d0d30fd570c 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(), |
