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.rs103
1 files changed, 44 insertions, 59 deletions
diff --git a/crates/hir-ty/src/next_solver/consts.rs b/crates/hir-ty/src/next_solver/consts.rs
index 0b3582051b..2fc1fc4f45 100644
--- a/crates/hir-ty/src/next_solver/consts.rs
+++ b/crates/hir-ty/src/next_solver/consts.rs
@@ -4,10 +4,11 @@ use std::hash::Hash;
use hir_def::{ConstParamId, TypeOrConstParamId};
use intern::{Interned, Symbol};
+use macros::{TypeFoldable, TypeVisitable};
use rustc_ast_ir::{try_visit, visit::VisitorResult};
use rustc_type_ir::{
- BoundVar, FlagComputation, Flags, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable,
- TypeVisitable, TypeVisitableExt, WithCachedTypeInfo,
+ BoundVar, DebruijnIndex, FlagComputation, Flags, TypeFoldable, TypeSuperFoldable,
+ TypeSuperVisitable, TypeVisitable, TypeVisitableExt, WithCachedTypeInfo,
inherent::{IntoKind, ParamEnv as _, PlaceholderLike, SliceLike},
relate::Relate,
};
@@ -23,7 +24,7 @@ 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_, debug)]
+#[salsa::interned(constructor = new_)]
pub struct Const<'db> {
#[returns(ref)]
kind_: InternedWrapperNoDebug<WithCachedTypeInfo<ConstKind<'db>>>,
@@ -41,13 +42,12 @@ impl<'db> Const<'db> {
}
pub fn inner(&self) -> &WithCachedTypeInfo<ConstKind<'db>> {
- salsa::with_attached_database(|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) }
})
- .unwrap()
}
pub fn error(interner: DbInterner<'db>) -> Self {
@@ -62,6 +62,25 @@ impl<'db> Const<'db> {
Const::new(interner, ConstKind::Placeholder(placeholder))
}
+ pub fn new_bound(interner: DbInterner<'db>, index: DebruijnIndex, bound: BoundConst) -> Self {
+ Const::new(interner, ConstKind::Bound(index, bound))
+ }
+
+ pub fn new_valtree(
+ interner: DbInterner<'db>,
+ ty: Ty<'db>,
+ memory: Box<[u8]>,
+ memory_map: MemoryMap<'db>,
+ ) -> Self {
+ Const::new(
+ interner,
+ ConstKind::Value(ValueConst {
+ ty,
+ value: Valtree::new(ConstBytes { memory, memory_map }),
+ }),
+ )
+ }
+
pub fn is_ct_infer(&self) -> bool {
matches!(&self.inner().internee, ConstKind::Infer(_))
}
@@ -78,6 +97,12 @@ impl<'db> Const<'db> {
}
}
+impl<'db> std::fmt::Debug for Const<'db> {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ self.inner().internee.fmt(f)
+ }
+}
+
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)
@@ -136,10 +161,13 @@ impl ParamConst {
/// A type-level constant value.
///
/// Represents a typed, fully evaluated constant.
-#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, TypeFoldable, TypeVisitable)]
pub struct ValueConst<'db> {
- pub(crate) ty: Ty<'db>,
- pub(crate) value: Valtree<'db>,
+ pub ty: Ty<'db>,
+ // FIXME: Should we ignore this for TypeVisitable, TypeFoldable?
+ #[type_visitable(ignore)]
+ #[type_foldable(identity)]
+ pub value: Valtree<'db>,
}
impl<'db> ValueConst<'db> {
@@ -159,33 +187,15 @@ impl<'db> rustc_type_ir::inherent::ValueConst<DbInterner<'db>> for ValueConst<'d
}
}
-impl<'db> rustc_type_ir::TypeVisitable<DbInterner<'db>> for ValueConst<'db> {
- fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
- &self,
- visitor: &mut V,
- ) -> V::Result {
- self.ty.visit_with(visitor)
- }
-}
-
-impl<'db> rustc_type_ir::TypeFoldable<DbInterner<'db>> for ValueConst<'db> {
- fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
- ValueConst { ty: self.ty.fold_with(folder), value: self.value }
- }
- fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
- self,
- folder: &mut F,
- ) -> Result<Self, F::Error> {
- Ok(ValueConst { ty: self.ty.try_fold_with(folder)?, value: self.value })
- }
-}
-
#[derive(Debug, Clone, PartialEq, Eq)]
-pub struct ConstBytes<'db>(pub Box<[u8]>, pub MemoryMap<'db>);
+pub struct ConstBytes<'db> {
+ pub memory: Box<[u8]>,
+ pub memory_map: MemoryMap<'db>,
+}
impl Hash for ConstBytes<'_> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
- self.0.hash(state)
+ self.memory.hash(state)
}
}
@@ -197,25 +207,23 @@ pub struct Valtree<'db> {
impl<'db> Valtree<'db> {
pub fn new(bytes: ConstBytes<'db>) -> Self {
- salsa::with_attached_database(|db| unsafe {
+ crate::with_attached_db(|db| unsafe {
// SAFETY: ¯\_(ツ)_/¯
std::mem::transmute(Valtree::new_(db, bytes))
})
- .unwrap()
}
pub fn inner(&self) -> &ConstBytes<'db> {
- salsa::with_attached_database(|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) }
})
- .unwrap()
}
}
-#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, TypeVisitable, TypeFoldable)]
pub struct ExprConst;
impl rustc_type_ir::inherent::ParamLike for ParamConst {
@@ -415,29 +423,6 @@ impl<'db> PlaceholderLike<DbInterner<'db>> for PlaceholderConst {
}
}
-impl<'db> TypeVisitable<DbInterner<'db>> for ExprConst {
- fn visit_with<V: rustc_type_ir::TypeVisitor<DbInterner<'db>>>(
- &self,
- visitor: &mut V,
- ) -> V::Result {
- // Ensure we get back to this when we fill in the fields
- let ExprConst = &self;
- V::Result::output()
- }
-}
-
-impl<'db> TypeFoldable<DbInterner<'db>> for ExprConst {
- fn try_fold_with<F: rustc_type_ir::FallibleTypeFolder<DbInterner<'db>>>(
- self,
- folder: &mut F,
- ) -> Result<Self, F::Error> {
- Ok(ExprConst)
- }
- fn fold_with<F: rustc_type_ir::TypeFolder<DbInterner<'db>>>(self, folder: &mut F) -> Self {
- ExprConst
- }
-}
-
impl<'db> Relate<DbInterner<'db>> for ExprConst {
fn relate<R: rustc_type_ir::relate::TypeRelation<DbInterner<'db>>>(
relation: &mut R,