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.rs164
1 files changed, 19 insertions, 145 deletions
diff --git a/crates/hir-ty/src/next_solver/consts.rs b/crates/hir-ty/src/next_solver/consts.rs
index 8ed515b452..fa90e3d8a0 100644
--- a/crates/hir-ty/src/next_solver/consts.rs
+++ b/crates/hir-ty/src/next_solver/consts.rs
@@ -1,5 +1,7 @@
//! Things related to consts in the next-trait-solver.
+mod valtree;
+
use std::hash::Hash;
use hir_def::ConstParamId;
@@ -9,21 +11,20 @@ use rustc_ast_ir::visit::VisitorResult;
use rustc_type_ir::{
BoundVar, BoundVarIndexKind, ConstVid, DebruijnIndex, FlagComputation, Flags,
GenericTypeVisitable, InferConst, TypeFoldable, TypeSuperFoldable, TypeSuperVisitable,
- TypeVisitable, TypeVisitableExt, WithCachedTypeInfo,
- inherent::{IntoKind, ParamEnv as _, SliceLike},
- relate::Relate,
+ TypeVisitable, WithCachedTypeInfo, inherent::IntoKind, relate::Relate,
};
use crate::{
- MemoryMap,
+ ParamEnvAndCrate,
next_solver::{
- ClauseKind, ParamEnv, impl_foldable_for_interned_slice, impl_stored_interned,
- interned_slice,
+ AllocationData, impl_foldable_for_interned_slice, impl_stored_interned, interned_slice,
},
};
use super::{DbInterner, ErrorGuaranteed, GenericArgs, Ty};
+pub use self::valtree::*;
+
pub type ConstKind<'db> = rustc_type_ir::ConstKind<DbInterner<'db>>;
pub type UnevaluatedConst<'db> = rustc_type_ir::UnevaluatedConst<DbInterner<'db>>;
@@ -86,18 +87,21 @@ impl<'db> Const<'db> {
Const::new(interner, ConstKind::Bound(BoundVarIndexKind::Bound(index), bound))
}
- pub fn new_valtree(
+ pub fn new_valtree(interner: DbInterner<'db>, ty: Ty<'db>, kind: ValTreeKind<'db>) -> Self {
+ Const::new(interner, ConstKind::Value(ValueConst { ty, value: ValTree::new(kind) }))
+ }
+
+ pub fn new_from_allocation(
interner: DbInterner<'db>,
- ty: Ty<'db>,
- memory: Box<[u8]>,
- memory_map: MemoryMap<'db>,
+ allocation: &AllocationData<'db>,
+ param_env: ParamEnvAndCrate<'db>,
) -> Self {
- Const::new(
+ allocation_to_const(
interner,
- ConstKind::Value(ValueConst {
- ty,
- value: Valtree::new(ConstBytes { memory, memory_map }),
- }),
+ allocation.ty,
+ &allocation.memory,
+ &allocation.memory_map,
+ param_env,
)
}
@@ -142,136 +146,6 @@ impl std::fmt::Debug for ParamConst {
}
}
-impl ParamConst {
- pub fn find_const_ty_from_env<'db>(self, env: ParamEnv<'db>) -> Ty<'db> {
- let mut candidates = env.caller_bounds().iter().filter_map(|clause| {
- // `ConstArgHasType` are never desugared to be higher ranked.
- match clause.kind().skip_binder() {
- ClauseKind::ConstArgHasType(param_ct, ty) => {
- assert!(!(param_ct, ty).has_escaping_bound_vars());
-
- match param_ct.kind() {
- ConstKind::Param(param_ct) if param_ct.index == self.index => Some(ty),
- _ => None,
- }
- }
- _ => None,
- }
- });
-
- // N.B. it may be tempting to fix ICEs by making this function return
- // `Option<Ty<'db>>` instead of `Ty<'db>`; however, this is generally
- // considered to be a bandaid solution, since it hides more important
- // underlying issues with how we construct generics and predicates of
- // items. It's advised to fix the underlying issue rather than trying
- // to modify this function.
- let ty = candidates.next().unwrap_or_else(|| {
- panic!("cannot find `{self:?}` in param-env: {env:#?}");
- });
- assert!(
- candidates.next().is_none(),
- "did not expect duplicate `ConstParamHasTy` for `{self:?}` in param-env: {env:#?}"
- );
- ty
- }
-}
-
-pub type ValTreeKind<'db> = rustc_type_ir::ValTreeKind<DbInterner<'db>>;
-
-/// A type-level constant value.
-///
-/// Represents a typed, fully evaluated constant.
-#[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?
- #[type_visitable(ignore)]
- #[type_foldable(identity)]
- pub value: Valtree<'db>,
-}
-
-impl<'db> ValueConst<'db> {
- pub fn new(ty: Ty<'db>, bytes: ConstBytes<'db>) -> Self {
- let value = Valtree::new(bytes);
- ValueConst { ty, value }
- }
-}
-
-impl<'db> rustc_type_ir::inherent::ValueConst<DbInterner<'db>> for ValueConst<'db> {
- fn ty(self) -> Ty<'db> {
- self.ty
- }
-
- fn valtree(self) -> Valtree<'db> {
- self.value
- }
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, GenericTypeVisitable)]
-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.memory.hash(state)
- }
-}
-
-#[derive(Clone, Copy, PartialEq, Eq, Hash)]
-pub struct Valtree<'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> IntoKind for Valtree<'db> {
- type Kind = ValTreeKind<'db>;
-
- fn kind(self) -> Self::Kind {
- todo!()
- }
-}
-
-impl<'db> Valtree<'db> {
- #[inline]
- pub fn new(bytes: ConstBytes<'db>) -> Self {
- 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> {
- 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, GenericTypeVisitable,
)]