Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/region.rs')
| -rw-r--r-- | crates/hir-ty/src/next_solver/region.rs | 68 |
1 files changed, 46 insertions, 22 deletions
diff --git a/crates/hir-ty/src/next_solver/region.rs b/crates/hir-ty/src/next_solver/region.rs index 3be715ab07..e34e87601f 100644 --- a/crates/hir-ty/src/next_solver/region.rs +++ b/crates/hir-ty/src/next_solver/region.rs @@ -1,47 +1,51 @@ //! Things related to regions. use hir_def::LifetimeParamId; -use intern::Symbol; +use intern::{Interned, InternedRef, Symbol, impl_internable}; +use macros::GenericTypeVisitable; use rustc_type_ir::{ - BoundVar, BoundVarIndexKind, DebruijnIndex, Flags, INNERMOST, RegionVid, TypeFlags, - TypeFoldable, TypeVisitable, + BoundVar, BoundVarIndexKind, DebruijnIndex, Flags, GenericTypeVisitable, INNERMOST, RegionVid, + TypeFlags, TypeFoldable, TypeVisitable, inherent::{IntoKind, PlaceholderLike, SliceLike}, relate::Relate, }; -use crate::next_solver::{GenericArg, OutlivesPredicate}; +use crate::next_solver::{ + GenericArg, OutlivesPredicate, impl_foldable_for_interned_slice, interned_slice, +}; use super::{ - ErrorGuaranteed, SolverDefId, interned_vec_db, + ErrorGuaranteed, SolverDefId, interner::{BoundVarKind, DbInterner, Placeholder}, }; pub type RegionKind<'db> = rustc_type_ir::RegionKind<DbInterner<'db>>; -#[salsa::interned(constructor = new_, unsafe(non_update_types))] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Region<'db> { - #[returns(ref)] - kind_: RegionKind<'db>, + pub(super) interned: InternedRef<'db, RegionInterned>, } -impl std::fmt::Debug for Region<'_> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.kind().fmt(f) - } -} +#[derive(PartialEq, Eq, Hash, GenericTypeVisitable)] +#[repr(align(4))] // Required for `GenericArg` bit-tagging. +pub(super) struct RegionInterned(RegionKind<'static>); + +impl_internable!(gc; RegionInterned); + +const _: () = { + const fn is_copy<T: Copy>() {} + is_copy::<Region<'static>>(); +}; impl<'db> Region<'db> { - pub fn new(interner: DbInterner<'db>, kind: RegionKind<'db>) -> Self { - Region::new_(interner.db(), kind) + pub fn new(_interner: DbInterner<'db>, kind: RegionKind<'db>) -> Self { + let kind = unsafe { std::mem::transmute::<RegionKind<'db>, RegionKind<'static>>(kind) }; + Self { interned: Interned::new_gc(RegionInterned(kind)) } } pub fn inner(&self) -> &RegionKind<'db> { - crate::with_attached_db(|db| { - let inner = self.kind_(db); - // SAFETY: The caller already has access to a `Region<'db>`, so borrowchecking will - // make sure that our returned value is valid for the lifetime `'db`. - unsafe { std::mem::transmute::<&RegionKind<'_>, &RegionKind<'db>>(inner) } - }) + let inner = &self.interned.0; + unsafe { std::mem::transmute::<&RegionKind<'static>, &RegionKind<'db>>(inner) } } pub fn new_early_param( @@ -256,6 +260,12 @@ impl BoundRegionKind { } } +impl std::fmt::Debug for Region<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.kind().fmt(f) + } +} + impl<'db> IntoKind for Region<'db> { type Kind = RegionKind<'db>; @@ -377,6 +387,20 @@ impl<'db> PlaceholderLike<DbInterner<'db>> for PlaceholderRegion { } } +impl<'db, V: super::WorldExposer> GenericTypeVisitable<V> for Region<'db> { + fn generic_visit_with(&self, visitor: &mut V) { + if visitor.on_interned(self.interned).is_continue() { + self.kind().generic_visit_with(visitor); + } + } +} + type GenericArgOutlivesPredicate<'db> = OutlivesPredicate<'db, GenericArg<'db>>; -interned_vec_db!(RegionAssumptions, GenericArgOutlivesPredicate); +interned_slice!( + RegionAssumptionsStorage, + RegionAssumptions, + GenericArgOutlivesPredicate<'db>, + GenericArgOutlivesPredicate<'static>, +); +impl_foldable_for_interned_slice!(RegionAssumptions); |