1- use  rustc_macros:: { HashStable ,  TyDecodable ,  TyEncodable ,  TypeFoldable ,  TypeVisitable } ; 
1+ use  std:: fmt; 
2+ use  std:: ops:: Deref ; 
3+ 
4+ use  rustc_data_structures:: intern:: Interned ; 
5+ use  rustc_macros:: { HashStable ,  Lift ,  TyDecodable ,  TyEncodable ,  TypeFoldable ,  TypeVisitable } ; 
26
37use  super :: ScalarInt ; 
48use  crate :: mir:: interpret:: Scalar ; 
@@ -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  ValTreeKind < ' 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,58 +37,97 @@ 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 >  ValTreeKind < ' 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 `ValTreeKind`, whenever possible. 
80+ /// 
81+ /// See the docs of [`ValTreeKind`] 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 ,  ValTreeKind < ' 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 ,  ValTreeKind :: Branch ( box [ ] ) ) 
95+     } 
96+ 
97+     pub  fn  from_raw_bytes ( tcx :  TyCtxt < ' tcx > ,  bytes :  & [ u8 ] )  -> Self  { 
98+         let  branches = bytes. iter ( ) . map ( |& b| Self :: from_scalar_int ( tcx,  b. into ( ) ) ) ; 
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 ( ValTreeKind :: Branch ( branches. into_iter ( ) . collect ( ) ) ) 
104+     } 
105+ 
106+     pub  fn  from_scalar_int ( tcx :  TyCtxt < ' tcx > ,  i :  ScalarInt )  -> Self  { 
107+         tcx. mk_valtree ( ValTreeKind :: Leaf ( i) ) 
108+     } 
109+ } 
110+ 
111+ impl < ' tcx >  Deref  for  ValTree < ' tcx >  { 
112+     type  Target  = & ' tcx  ValTreeKind < ' tcx > ; 
113+ 
114+     #[ inline]  
115+     fn  deref ( & self )  -> & & ' tcx  ValTreeKind < ' tcx >  { 
116+         & self . 0 . 0 
117+     } 
118+ } 
119+ 
120+ impl  fmt:: Debug  for  ValTree < ' _ >  { 
121+     fn  fmt ( & self ,  f :  & mut  fmt:: Formatter < ' _ > )  -> fmt:: Result  { 
122+         ( * * self ) . fmt ( f) 
80123    } 
81124} 
82125
83126/// A type-level constant value. 
84127/// 
85128/// Represents a typed, fully evaluated constant. 
86129#[ derive( Copy ,  Clone ,  Debug ,  Hash ,  Eq ,  PartialEq ) ]  
87- #[ derive( HashStable ,  TyEncodable ,  TyDecodable ,  TypeFoldable ,  TypeVisitable ) ]  
130+ #[ derive( HashStable ,  TyEncodable ,  TyDecodable ,  TypeFoldable ,  TypeVisitable ,   Lift ) ]  
88131pub  struct  Value < ' tcx >  { 
89132    pub  ty :  Ty < ' tcx > , 
90133    pub  valtree :  ValTree < ' tcx > , 
0 commit comments