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 | 67 |
1 files changed, 57 insertions, 10 deletions
diff --git a/crates/hir-ty/src/next_solver/region.rs b/crates/hir-ty/src/next_solver/region.rs index d6214d9915..19f3c38b67 100644 --- a/crates/hir-ty/src/next_solver/region.rs +++ b/crates/hir-ty/src/next_solver/region.rs @@ -1,9 +1,10 @@ //! Things related to regions. use hir_def::LifetimeParamId; -use intern::{Interned, Symbol}; +use intern::Symbol; use rustc_type_ir::{ - BoundVar, Flags, INNERMOST, RegionVid, TypeFlags, TypeFoldable, TypeVisitable, VisitorResult, + BoundVar, BoundVarIndexKind, DebruijnIndex, Flags, INNERMOST, RegionVid, TypeFlags, + TypeFoldable, TypeVisitable, inherent::{IntoKind, PlaceholderLike, SliceLike}, relate::Relate, }; @@ -15,27 +16,32 @@ use super::{ interner::{BoundVarKind, DbInterner, Placeholder}, }; -type RegionKind<'db> = rustc_type_ir::RegionKind<DbInterner<'db>>; +pub type RegionKind<'db> = rustc_type_ir::RegionKind<DbInterner<'db>>; -#[salsa::interned(constructor = new_, debug)] +#[salsa::interned(constructor = new_)] pub struct Region<'db> { #[returns(ref)] kind_: RegionKind<'db>, } +impl std::fmt::Debug for Region<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.kind().fmt(f) + } +} + impl<'db> Region<'db> { pub fn new(interner: DbInterner<'db>, kind: RegionKind<'db>) -> Self { Region::new_(interner.db(), kind) } pub fn inner(&self) -> &RegionKind<'db> { - salsa::with_attached_database(|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) } }) - .unwrap() } pub fn new_early_param( @@ -53,6 +59,18 @@ impl<'db> Region<'db> { Region::new(interner, RegionKind::ReVar(v)) } + pub fn new_erased(interner: DbInterner<'db>) -> Region<'db> { + Region::new(interner, RegionKind::ReErased) + } + + pub fn new_bound( + interner: DbInterner<'db>, + index: DebruijnIndex, + bound: BoundRegion, + ) -> Region<'db> { + Region::new(interner, RegionKind::ReBound(BoundVarIndexKind::Bound(index), bound)) + } + pub fn is_placeholder(&self) -> bool { matches!(self.inner(), RegionKind::RePlaceholder(..)) } @@ -61,6 +79,18 @@ 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(_)) + } + + pub fn is_error(&self) -> bool { + matches!(self.inner(), RegionKind::ReError(_)) + } + pub fn error(interner: DbInterner<'db>) -> Self { Region::new(interner, RegionKind::ReError(ErrorGuaranteed)) } @@ -91,7 +121,11 @@ impl<'db> Region<'db> { RegionKind::ReStatic => { flags |= TypeFlags::HAS_FREE_REGIONS; } - RegionKind::ReBound(..) => { + RegionKind::ReBound(BoundVarIndexKind::Canonical, ..) => { + flags |= TypeFlags::HAS_RE_BOUND; + flags |= TypeFlags::HAS_CANONICAL_BOUND; + } + RegionKind::ReBound(BoundVarIndexKind::Bound(..), ..) => { flags |= TypeFlags::HAS_RE_BOUND; } RegionKind::ReErased => { @@ -268,7 +302,7 @@ impl<'db> Flags for Region<'db> { fn outer_exclusive_binder(&self) -> rustc_type_ir::DebruijnIndex { match &self.inner() { - RegionKind::ReBound(debruijn, _) => debruijn.shifted_in(1), + RegionKind::ReBound(BoundVarIndexKind::Bound(debruijn), _) => debruijn.shifted_in(1), _ => INNERMOST, } } @@ -280,7 +314,7 @@ impl<'db> rustc_type_ir::inherent::Region<DbInterner<'db>> for Region<'db> { debruijn: rustc_type_ir::DebruijnIndex, var: BoundRegion, ) -> Self { - Region::new(interner, RegionKind::ReBound(debruijn, var)) + Region::new(interner, RegionKind::ReBound(BoundVarIndexKind::Bound(debruijn), var)) } fn new_anon_bound( @@ -290,7 +324,20 @@ impl<'db> rustc_type_ir::inherent::Region<DbInterner<'db>> for Region<'db> { ) -> Self { Region::new( interner, - RegionKind::ReBound(debruijn, BoundRegion { var, kind: BoundRegionKind::Anon }), + RegionKind::ReBound( + BoundVarIndexKind::Bound(debruijn), + BoundRegion { var, kind: BoundRegionKind::Anon }, + ), + ) + } + + fn new_canonical_bound(interner: DbInterner<'db>, var: rustc_type_ir::BoundVar) -> Self { + Region::new( + interner, + RegionKind::ReBound( + BoundVarIndexKind::Canonical, + BoundRegion { var, kind: BoundRegionKind::Anon }, + ), ) } |