1+ use std:: ops:: Deref ;
2+
3+ use rustc_data_structures:: intern:: Interned ;
14use rustc_macros:: { HashStable , TyDecodable , TyEncodable , TypeFoldable , TypeVisitable } ;
25
36use super :: ScalarInt ;
@@ -16,9 +19,9 @@ use crate::ty::{self, Ty, TyCtxt};
1619///
1720/// `ValTree` does not have this problem with representation, as it only contains integers or
1821/// lists of (nested) `ValTree`.
19- #[ derive( Copy , Clone , Debug , Hash , Eq , PartialEq ) ]
22+ #[ derive( Clone , Debug , Hash , Eq , PartialEq ) ]
2023#[ derive( HashStable , TyEncodable , TyDecodable ) ]
21- pub enum ValTree < ' tcx > {
24+ pub enum ValTreeData < ' tcx > {
2225 /// integers, `bool`, `char` are represented as scalars.
2326 /// See the `ScalarInt` documentation for how `ScalarInt` guarantees that equal values
2427 /// of these types have the same representation.
@@ -33,50 +36,82 @@ pub enum ValTree<'tcx> {
3336 /// the fields of the variant.
3437 ///
3538 /// ZST types are represented as an empty slice.
36- Branch ( & ' tcx [ ValTree < ' tcx > ] ) ,
39+ Branch ( Box < [ ValTree < ' tcx > ] > ) ,
3740}
3841
39- impl < ' tcx > ValTree < ' tcx > {
40- pub fn zst ( ) -> Self {
41- Self :: Branch ( & [ ] )
42- }
43-
42+ impl < ' tcx > ValTreeData < ' tcx > {
4443 #[ inline]
45- pub fn unwrap_leaf ( self ) -> ScalarInt {
44+ pub fn unwrap_leaf ( & self ) -> ScalarInt {
4645 match self {
47- Self :: Leaf ( s) => s,
46+ Self :: Leaf ( s) => * s,
4847 _ => bug ! ( "expected leaf, got {:?}" , self ) ,
4948 }
5049 }
5150
5251 #[ inline]
53- pub fn unwrap_branch ( self ) -> & ' tcx [ Self ] {
52+ pub fn unwrap_branch ( & self ) -> & [ ValTree < ' tcx > ] {
5453 match self {
55- Self :: Branch ( branch) => branch,
54+ Self :: Branch ( branch) => & * * branch,
5655 _ => bug ! ( "expected branch, got {:?}" , self ) ,
5756 }
5857 }
5958
60- pub fn from_raw_bytes < ' a > ( tcx : TyCtxt < ' tcx > , bytes : & ' a [ u8 ] ) -> Self {
61- let branches = bytes . iter ( ) . map ( |b| Self :: Leaf ( ScalarInt :: from ( * b ) ) ) ;
62- let interned = tcx . arena . alloc_from_iter ( branches ) ;
59+ pub fn try_to_scalar ( & self ) -> Option < Scalar > {
60+ self . try_to_scalar_int ( ) . map ( Scalar :: Int )
61+ }
6362
64- Self :: Branch ( interned)
63+ pub fn try_to_scalar_int ( & self ) -> Option < ScalarInt > {
64+ match self {
65+ Self :: Leaf ( s) => Some ( * s) ,
66+ Self :: Branch ( _) => None ,
67+ }
6568 }
6669
67- pub fn from_scalar_int ( i : ScalarInt ) -> Self {
68- Self :: Leaf ( i)
70+ pub fn try_to_branch ( & self ) -> Option < & [ ValTree < ' tcx > ] > {
71+ match self {
72+ Self :: Branch ( branch) => Some ( & * * branch) ,
73+ Self :: Leaf ( _) => None ,
74+ }
6975 }
76+ }
7077
71- pub fn try_to_scalar ( self ) -> Option < Scalar > {
72- self . try_to_scalar_int ( ) . map ( Scalar :: Int )
78+ /// An interned valtree. Use this rather than `ValTreeData`, whenever possible.
79+ ///
80+ /// See the docs of [`ValTreeData`] or the [dev guide] for an explanation of this type.
81+ ///
82+ /// [dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html#valtrees
83+ #[ derive( Copy , Clone , Debug , Hash , Eq , PartialEq ) ]
84+ #[ derive( HashStable ) ]
85+ pub struct ValTree < ' tcx > ( pub ( crate ) Interned < ' tcx , ValTreeData < ' tcx > > ) ;
86+
87+ impl < ' tcx > ValTree < ' tcx > {
88+ pub fn zst ( tcx : TyCtxt < ' tcx > ) -> Self {
89+ tcx. consts . valtree_zst
7390 }
7491
75- pub fn try_to_scalar_int ( self ) -> Option < ScalarInt > {
76- match self {
77- Self :: Leaf ( s) => Some ( s) ,
78- Self :: Branch ( _) => None ,
79- }
92+ pub fn is_zst ( self ) -> bool {
93+ matches ! ( * self , ValTreeData :: Branch ( box [ ] ) )
94+ }
95+
96+ pub fn from_raw_bytes ( tcx : TyCtxt < ' tcx > , bytes : & [ u8 ] ) -> Self {
97+ let branches = bytes. iter ( ) . map ( |b| tcx. mk_valtree ( ValTreeData :: Leaf ( ScalarInt :: from ( * b) ) ) ) ;
98+ Self :: from_branches ( tcx, branches)
99+ }
100+
101+ pub fn from_branches ( tcx : TyCtxt < ' tcx > , branches : impl IntoIterator < Item = Self > ) -> Self {
102+ tcx. mk_valtree ( ValTreeData :: Branch ( branches. into_iter ( ) . collect ( ) ) )
103+ }
104+
105+ pub fn from_scalar_int ( tcx : TyCtxt < ' tcx > , i : ScalarInt ) -> Self {
106+ tcx. mk_valtree ( ValTreeData :: Leaf ( i) )
107+ }
108+ }
109+
110+ impl < ' tcx > Deref for ValTree < ' tcx > {
111+ type Target = & ' tcx ValTreeData < ' tcx > ;
112+
113+ fn deref ( & self ) -> & & ' tcx ValTreeData < ' tcx > {
114+ & self . 0 . 0
80115 }
81116}
82117
0 commit comments