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 | 164 |
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, )] |