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.rs82
1 files changed, 57 insertions, 25 deletions
diff --git a/crates/hir-ty/src/next_solver/region.rs b/crates/hir-ty/src/next_solver/region.rs
index b5f0e6de29..dc2441f76e 100644
--- a/crates/hir-ty/src/next_solver/region.rs
+++ b/crates/hir-ty/src/next_solver/region.rs
@@ -1,47 +1,53 @@
//! 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, impl_stored_interned,
+ interned_slice,
+};
use super::{
- ErrorGuaranteed, SolverDefId, interned_vec_db,
+ SolverDefId,
interner::{BoundVarKind, DbInterner, Placeholder},
};
pub type RegionKind<'db> = rustc_type_ir::RegionKind<DbInterner<'db>>;
-#[salsa::interned(constructor = new_)]
+#[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);
+impl_stored_interned!(RegionInterned, Region, StoredRegion);
+
+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(
@@ -60,7 +66,7 @@ impl<'db> Region<'db> {
}
pub fn new_erased(interner: DbInterner<'db>) -> Region<'db> {
- Region::new(interner, RegionKind::ReErased)
+ interner.default_types().regions.erased
}
pub fn new_bound(
@@ -79,6 +85,10 @@ impl<'db> Region<'db> {
matches!(self.inner(), RegionKind::ReStatic)
}
+ pub fn is_erased(&self) -> bool {
+ matches!(self.inner(), RegionKind::ReErased)
+ }
+
pub fn is_var(&self) -> bool {
matches!(self.inner(), RegionKind::ReVar(_))
}
@@ -88,7 +98,7 @@ impl<'db> Region<'db> {
}
pub fn error(interner: DbInterner<'db>) -> Self {
- Region::new(interner, RegionKind::ReError(ErrorGuaranteed))
+ interner.default_types().regions.error
}
pub fn type_flags(&self) -> TypeFlags {
@@ -252,6 +262,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>;
@@ -338,7 +354,7 @@ impl<'db> rustc_type_ir::inherent::Region<DbInterner<'db>> for Region<'db> {
}
fn new_static(interner: DbInterner<'db>) -> Self {
- Region::new(interner, RegionKind::ReStatic)
+ interner.default_types().regions.statik
}
fn new_placeholder(
@@ -373,6 +389,22 @@ 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,
+ StoredRegionAssumptions,
+ region_assumptions,
+ GenericArgOutlivesPredicate<'db>,
+ GenericArgOutlivesPredicate<'static>,
+);
+impl_foldable_for_interned_slice!(RegionAssumptions);