Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/consts.rs')
| -rw-r--r-- | crates/hir-ty/src/next_solver/consts.rs | 121 |
1 files changed, 80 insertions, 41 deletions
diff --git a/crates/hir-ty/src/next_solver/consts.rs b/crates/hir-ty/src/next_solver/consts.rs index 926dbdc03d..9643f1ba4c 100644 --- a/crates/hir-ty/src/next_solver/consts.rs +++ b/crates/hir-ty/src/next_solver/consts.rs @@ -3,19 +3,20 @@ use std::hash::Hash; use hir_def::ConstParamId; -use macros::{TypeFoldable, TypeVisitable}; +use intern::{Interned, InternedRef, impl_internable}; +use macros::{GenericTypeVisitable, TypeFoldable, TypeVisitable}; use rustc_ast_ir::visit::VisitorResult; use rustc_type_ir::{ - BoundVar, BoundVarIndexKind, ConstVid, DebruijnIndex, FlagComputation, Flags, InferConst, - TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, - WithCachedTypeInfo, + BoundVar, BoundVarIndexKind, ConstVid, DebruijnIndex, FlagComputation, Flags, + GenericTypeVisitable, InferConst, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable, + TypeVisitable, TypeVisitableExt, WithCachedTypeInfo, inherent::{IntoKind, ParamEnv as _, PlaceholderLike, SliceLike}, relate::Relate, }; use crate::{ MemoryMap, - next_solver::{ClauseKind, ParamEnv, interner::InternedWrapperNoDebug}, + next_solver::{ClauseKind, ParamEnv, impl_stored_interned}, }; use super::{BoundVarKind, DbInterner, ErrorGuaranteed, GenericArgs, Placeholder, Ty}; @@ -23,34 +24,47 @@ use super::{BoundVarKind, DbInterner, ErrorGuaranteed, GenericArgs, Placeholder, pub type ConstKind<'db> = rustc_type_ir::ConstKind<DbInterner<'db>>; pub type UnevaluatedConst<'db> = rustc_type_ir::UnevaluatedConst<DbInterner<'db>>; -#[salsa::interned(constructor = new_)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Const<'db> { - #[returns(ref)] - kind_: InternedWrapperNoDebug<WithCachedTypeInfo<ConstKind<'db>>>, + pub(super) interned: InternedRef<'db, ConstInterned>, } +#[derive(PartialEq, Eq, Hash, GenericTypeVisitable)] +#[repr(align(4))] // Required for `GenericArg` bit-tagging. +pub(super) struct ConstInterned(pub(super) WithCachedTypeInfo<ConstKind<'static>>); + +impl_internable!(gc; ConstInterned); +impl_stored_interned!(ConstInterned, Const, StoredConst); + +const _: () = { + const fn is_copy<T: Copy>() {} + is_copy::<Const<'static>>(); +}; + impl<'db> Const<'db> { - pub fn new(interner: DbInterner<'db>, kind: ConstKind<'db>) -> Self { + pub fn new(_interner: DbInterner<'db>, kind: ConstKind<'db>) -> Self { + let kind = unsafe { std::mem::transmute::<ConstKind<'db>, ConstKind<'static>>(kind) }; let flags = FlagComputation::for_const_kind(&kind); let cached = WithCachedTypeInfo { internee: kind, flags: flags.flags, outer_exclusive_binder: flags.outer_exclusive_binder, }; - Const::new_(interner.db(), InternedWrapperNoDebug(cached)) + Self { interned: Interned::new_gc(ConstInterned(cached)) } } pub fn inner(&self) -> &WithCachedTypeInfo<ConstKind<'db>> { - crate::with_attached_db(|db| { - let inner = &self.kind_(db).0; - // SAFETY: The caller already has access to a `Const<'db>`, so borrowchecking will - // make sure that our returned value is valid for the lifetime `'db`. - unsafe { std::mem::transmute(inner) } - }) + let inner = &self.interned.0; + unsafe { + std::mem::transmute::< + &WithCachedTypeInfo<ConstKind<'static>>, + &WithCachedTypeInfo<ConstKind<'db>>, + >(inner) + } } pub fn error(interner: DbInterner<'db>) -> Self { - Const::new(interner, ConstKind::Error(ErrorGuaranteed)) + interner.default_types().consts.error } pub fn new_param(interner: DbInterner<'db>, param: ParamConst) -> Self { @@ -106,12 +120,6 @@ impl<'db> std::fmt::Debug for Const<'db> { } } -impl<'db> std::fmt::Debug for InternedWrapperNoDebug<WithCachedTypeInfo<ConstKind<'db>>> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - self.0.internee.fmt(f) - } -} - pub type PlaceholderConst = Placeholder<BoundConst>; #[derive(Copy, Clone, Hash, Eq, PartialEq)] @@ -164,7 +172,9 @@ impl ParamConst { /// A type-level constant value. /// /// Represents a typed, fully evaluated constant. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, TypeFoldable, TypeVisitable)] +#[derive( + Debug, Copy, Clone, Eq, PartialEq, Hash, TypeFoldable, TypeVisitable, GenericTypeVisitable, +)] pub struct ValueConst<'db> { pub ty: Ty<'db>, // FIXME: Should we ignore this for TypeVisitable, TypeFoldable? @@ -190,7 +200,7 @@ impl<'db> rustc_type_ir::inherent::ValueConst<DbInterner<'db>> for ValueConst<'d } } -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone, PartialEq, Eq, GenericTypeVisitable)] pub struct ConstBytes<'db> { pub memory: Box<[u8]>, pub memory_map: MemoryMap<'db>, @@ -202,31 +212,52 @@ impl Hash for ConstBytes<'_> { } } -#[salsa::interned(constructor = new_, debug)] +#[derive(Clone, Copy, PartialEq, Eq, Hash)] pub struct Valtree<'db> { - #[returns(ref)] - bytes_: ConstBytes<'db>, + interned: InternedRef<'db, ValtreeInterned>, +} + +impl<'db, V: super::WorldExposer> GenericTypeVisitable<V> for Valtree<'db> { + fn generic_visit_with(&self, visitor: &mut V) { + if visitor.on_interned(self.interned).is_continue() { + self.inner().generic_visit_with(visitor); + } + } } +#[derive(Debug, PartialEq, Eq, Hash, GenericTypeVisitable)] +pub(super) struct ValtreeInterned(ConstBytes<'static>); + +impl_internable!(gc; ValtreeInterned); + +const _: () = { + const fn is_copy<T: Copy>() {} + is_copy::<Valtree<'static>>(); +}; + impl<'db> Valtree<'db> { + #[inline] pub fn new(bytes: ConstBytes<'db>) -> Self { - crate::with_attached_db(|db| unsafe { - // SAFETY: ¯\_(ツ)_/¯ - std::mem::transmute(Valtree::new_(db, bytes)) - }) + let bytes = unsafe { std::mem::transmute::<ConstBytes<'db>, ConstBytes<'static>>(bytes) }; + Self { interned: Interned::new_gc(ValtreeInterned(bytes)) } } + #[inline] pub fn inner(&self) -> &ConstBytes<'db> { - crate::with_attached_db(|db| { - let inner = self.bytes_(db); - // SAFETY: The caller already has access to a `Valtree<'db>`, so borrowchecking will - // make sure that our returned value is valid for the lifetime `'db`. - unsafe { std::mem::transmute(inner) } - }) + let inner = &self.interned.0; + unsafe { std::mem::transmute::<&ConstBytes<'static>, &ConstBytes<'db>>(inner) } + } +} + +impl std::fmt::Debug for Valtree<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.interned.fmt(f) } } -#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeVisitable, TypeFoldable)] +#[derive( + Copy, Clone, Debug, Hash, PartialEq, Eq, TypeVisitable, TypeFoldable, GenericTypeVisitable, +)] pub struct ExprConst; impl rustc_type_ir::inherent::ParamLike for ParamConst { @@ -243,6 +274,14 @@ impl<'db> IntoKind for Const<'db> { } } +impl<'db, V: super::WorldExposer> GenericTypeVisitable<V> for Const<'db> { + fn generic_visit_with(&self, visitor: &mut V) { + if visitor.on_interned(self.interned).is_continue() { + self.kind().generic_visit_with(visitor); + } + } +} + impl<'db> TypeVisitable<DbInterner<'db>> for Const<'db> { fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>( &self, @@ -382,8 +421,8 @@ impl<'db> rustc_type_ir::inherent::Const<DbInterner<'db>> for Const<'db> { Const::new(interner, ConstKind::Expr(expr)) } - fn new_error(interner: DbInterner<'db>, guar: ErrorGuaranteed) -> Self { - Const::new(interner, ConstKind::Error(guar)) + fn new_error(interner: DbInterner<'db>, _guar: ErrorGuaranteed) -> Self { + Const::error(interner) } } |