1+ use std:: fmt;
2+ use std:: ops:: Deref ;
3+
4+ use rustc_data_structures:: intern:: Interned ;
15use rustc_macros:: { HashStable , TyDecodable , TyEncodable , TypeFoldable , TypeVisitable } ;
26
37use super :: ScalarInt ;
@@ -16,9 +20,9 @@ use crate::ty::{self, Ty, TyCtxt};
1620///
1721/// `ValTree` does not have this problem with representation, as it only contains integers or
1822/// lists of (nested) `ValTree`.
19- #[ derive( Copy , Clone , Debug , Hash , Eq , PartialEq ) ]
23+ #[ derive( Clone , Debug , Hash , Eq , PartialEq ) ]
2024#[ derive( HashStable , TyEncodable , TyDecodable ) ]
21- pub enum ValTree < ' tcx > {
25+ pub enum ValTreeData < ' tcx > {
2226 /// integers, `bool`, `char` are represented as scalars.
2327 /// See the `ScalarInt` documentation for how `ScalarInt` guarantees that equal values
2428 /// of these types have the same representation.
@@ -33,50 +37,88 @@ pub enum ValTree<'tcx> {
3337 /// the fields of the variant.
3438 ///
3539 /// ZST types are represented as an empty slice.
36- Branch ( & ' tcx [ ValTree < ' tcx > ] ) ,
40+ Branch ( Box < [ ValTree < ' tcx > ] > ) ,
3741}
3842
39- impl < ' tcx > ValTree < ' tcx > {
40- pub fn zst ( ) -> Self {
41- Self :: Branch ( & [ ] )
42- }
43-
43+ impl < ' tcx > ValTreeData < ' tcx > {
4444 #[ inline]
45- pub fn unwrap_leaf ( self ) -> ScalarInt {
45+ pub fn unwrap_leaf ( & self ) -> ScalarInt {
4646 match self {
47- Self :: Leaf ( s) => s,
47+ Self :: Leaf ( s) => * s,
4848 _ => bug ! ( "expected leaf, got {:?}" , self ) ,
4949 }
5050 }
5151
5252 #[ inline]
53- pub fn unwrap_branch ( self ) -> & ' tcx [ Self ] {
53+ pub fn unwrap_branch ( & self ) -> & [ ValTree < ' tcx > ] {
5454 match self {
55- Self :: Branch ( branch) => branch,
55+ Self :: Branch ( branch) => & * * branch,
5656 _ => bug ! ( "expected branch, got {:?}" , self ) ,
5757 }
5858 }
5959
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 ) ;
60+ pub fn try_to_scalar ( & self ) -> Option < Scalar > {
61+ self . try_to_scalar_int ( ) . map ( Scalar :: Int )
62+ }
6363
64- Self :: Branch ( interned)
64+ pub fn try_to_scalar_int ( & self ) -> Option < ScalarInt > {
65+ match self {
66+ Self :: Leaf ( s) => Some ( * s) ,
67+ Self :: Branch ( _) => None ,
68+ }
6569 }
6670
67- pub fn from_scalar_int ( i : ScalarInt ) -> Self {
68- Self :: Leaf ( i)
71+ pub fn try_to_branch ( & self ) -> Option < & [ ValTree < ' tcx > ] > {
72+ match self {
73+ Self :: Branch ( branch) => Some ( & * * branch) ,
74+ Self :: Leaf ( _) => None ,
75+ }
6976 }
77+ }
7078
71- pub fn try_to_scalar ( self ) -> Option < Scalar > {
72- self . try_to_scalar_int ( ) . map ( Scalar :: Int )
79+ /// An interned valtree. Use this rather than `ValTreeData`, whenever possible.
80+ ///
81+ /// See the docs of [`ValTreeData`] or the [dev guide] for an explanation of this type.
82+ ///
83+ /// [dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html#valtrees
84+ #[ derive( Copy , Clone , Hash , Eq , PartialEq ) ]
85+ #[ derive( HashStable ) ]
86+ pub struct ValTree < ' tcx > ( pub ( crate ) Interned < ' tcx , ValTreeData < ' tcx > > ) ;
87+
88+ impl < ' tcx > ValTree < ' tcx > {
89+ pub fn zst ( tcx : TyCtxt < ' tcx > ) -> Self {
90+ tcx. consts . valtree_zst
7391 }
7492
75- pub fn try_to_scalar_int ( self ) -> Option < ScalarInt > {
76- match self {
77- Self :: Leaf ( s) => Some ( s) ,
78- Self :: Branch ( _) => None ,
79- }
93+ pub fn is_zst ( self ) -> bool {
94+ matches ! ( * self , ValTreeData :: Branch ( box [ ] ) )
95+ }
96+
97+ pub fn from_raw_bytes ( tcx : TyCtxt < ' tcx > , bytes : & [ u8 ] ) -> Self {
98+ let branches = bytes. iter ( ) . map ( |b| tcx. mk_valtree ( ValTreeData :: Leaf ( ScalarInt :: from ( * b) ) ) ) ;
99+ Self :: from_branches ( tcx, branches)
100+ }
101+
102+ pub fn from_branches ( tcx : TyCtxt < ' tcx > , branches : impl IntoIterator < Item = Self > ) -> Self {
103+ tcx. mk_valtree ( ValTreeData :: Branch ( branches. into_iter ( ) . collect ( ) ) )
104+ }
105+
106+ pub fn from_scalar_int ( tcx : TyCtxt < ' tcx > , i : ScalarInt ) -> Self {
107+ tcx. mk_valtree ( ValTreeData :: Leaf ( i) )
108+ }
109+ }
110+
111+ impl < ' tcx > Deref for ValTree < ' tcx > {
112+ type Target = & ' tcx ValTreeData < ' tcx > ;
113+
114+ fn deref ( & self ) -> & & ' tcx ValTreeData < ' tcx > {
115+ & self . 0 . 0
116+ }
117+ }
118+
119+ impl fmt:: Debug for ValTree < ' _ > {
120+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
121+ ( * * self ) . fmt ( f)
80122 }
81123}
82124
0 commit comments