diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b0c066fb42f..49ab1084e58 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -789,7 +789,7 @@ rustc_queries! { /// return `None` if that is not possible. query const_to_valtree( key: ty::ParamEnvAnd<'tcx, ConstAlloc<'tcx>> - ) -> Option { + ) -> Option> { desc { "destructure constant" } } diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 73ad87a9ef2..f796534c2e1 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -333,6 +333,16 @@ impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for ty::Const<'tcx> { } } +impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for [ty::ValTree<'tcx>] { + fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { + Ok(decoder.tcx().arena.alloc_from_iter( + (0..decoder.read_usize()?) + .map(|_| Decodable::decode(decoder)) + .collect::, _>>()?, + )) + } +} + impl<'tcx, D: TyDecoder<'tcx>> RefDecodable<'tcx, D> for Allocation { fn decode(decoder: &mut D) -> Result<&'tcx Self, D::Error> { Ok(decoder.tcx().intern_const_alloc(Decodable::decode(decoder)?)) diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index 9b42023f054..6c8eea8c768 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -1,15 +1,15 @@ use super::ScalarInt; use rustc_macros::HashStable; -#[derive(Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)] +#[derive(Copy, Clone, Debug, Hash, TyEncodable, TyDecodable, Eq, PartialEq, Ord, PartialOrd)] #[derive(HashStable)] -pub enum ValTree { +pub enum ValTree<'tcx> { Leaf(ScalarInt), - Branch(Vec), + Branch(&'tcx [ValTree<'tcx>]), } -impl ValTree { +impl ValTree<'tcx> { pub fn zst() -> Self { - Self::Branch(Vec::new()) + Self::Branch(&[]) } } diff --git a/compiler/rustc_mir/src/const_eval/mod.rs b/compiler/rustc_mir/src/const_eval/mod.rs index fbd2d5d78a7..5e77cc9daf3 100644 --- a/compiler/rustc_mir/src/const_eval/mod.rs +++ b/compiler/rustc_mir/src/const_eval/mod.rs @@ -43,7 +43,7 @@ pub(crate) fn const_to_valtree<'tcx>( tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, raw: ConstAlloc<'tcx>, -) -> Option { +) -> Option> { let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env, false); let place = ecx.raw_const_to_mplace(raw).unwrap(); const_to_valtree_inner(&ecx, &place) @@ -52,7 +52,7 @@ pub(crate) fn const_to_valtree<'tcx>( fn const_to_valtree_inner<'tcx>( ecx: &CompileTimeEvalContext<'tcx, 'tcx>, place: &MPlaceTy<'tcx>, -) -> Option { +) -> Option> { let branches = |n, variant| { let place = match variant { Some(variant) => ecx.mplace_downcast(&place, variant).unwrap(), @@ -64,7 +64,11 @@ fn const_to_valtree_inner<'tcx>( let field = ecx.mplace_field(&place, i).unwrap(); const_to_valtree_inner(ecx, &field) }); - Some(ty::ValTree::Branch(variant.into_iter().chain(fields).collect::>()?)) + Some(ty::ValTree::Branch( + ecx.tcx + .arena + .alloc_from_iter(variant.into_iter().chain(fields).collect::>>()?), + )) }; match place.layout.ty.kind() { ty::FnDef(..) => Some(ty::ValTree::zst()),