@@ -3,74 +3,45 @@ use std::ops::Deref;
33
44use rustc_data_structures:: intern:: Interned ;
55use rustc_hir:: def:: Namespace ;
6- use rustc_macros:: { HashStable , Lift , TyDecodable , TyEncodable , TypeFoldable , TypeVisitable } ;
6+ use rustc_macros:: {
7+ HashStable , Lift , TyDecodable , TyEncodable , TypeFoldable , TypeVisitable , extension,
8+ } ;
79
810use super :: ScalarInt ;
911use crate :: mir:: interpret:: { ErrorHandled , Scalar } ;
1012use crate :: ty:: print:: { FmtPrinter , PrettyPrinter } ;
1113use crate :: ty:: { self , Ty , TyCtxt } ;
1214
13- /// This datastructure is used to represent the value of constants used in the type system.
14- ///
15- /// We explicitly choose a different datastructure from the way values are processed within
16- /// CTFE, as in the type system equal values (according to their `PartialEq`) must also have
17- /// equal representation (`==` on the rustc data structure, e.g. `ValTree`) and vice versa.
18- /// Since CTFE uses `AllocId` to represent pointers, it often happens that two different
19- /// `AllocId`s point to equal values. So we may end up with different representations for
20- /// two constants whose value is `&42`. Furthermore any kind of struct that has padding will
21- /// have arbitrary values within that padding, even if the values of the struct are the same.
22- ///
23- /// `ValTree` does not have this problem with representation, as it only contains integers or
24- /// lists of (nested) `ValTree`.
25- #[ derive( Clone , Debug , Hash , Eq , PartialEq ) ]
26- #[ derive( HashStable , TyEncodable , TyDecodable ) ]
27- pub enum ValTreeKind < ' tcx > {
28- /// integers, `bool`, `char` are represented as scalars.
29- /// See the `ScalarInt` documentation for how `ScalarInt` guarantees that equal values
30- /// of these types have the same representation.
31- Leaf ( ScalarInt ) ,
32-
33- //SliceOrStr(ValSlice<'tcx>),
34- // don't use SliceOrStr for now
35- /// The fields of any kind of aggregate. Structs, tuples and arrays are represented by
36- /// listing their fields' values in order.
37- ///
38- /// Enums are represented by storing their variant index as a u32 field, followed by all
39- /// the fields of the variant.
40- ///
41- /// ZST types are represented as an empty slice.
42- Branch ( Box < [ ValTree < ' tcx > ] > ) ,
43- }
44-
45- impl < ' tcx > ValTreeKind < ' tcx > {
15+ #[ extension( pub trait ValTreeKindExt <' tcx>) ]
16+ impl < ' tcx > ty:: ValTreeKind < TyCtxt < ' tcx > > {
4617 #[ inline]
47- pub fn unwrap_leaf ( & self ) -> ScalarInt {
18+ fn unwrap_leaf ( & self ) -> ScalarInt {
4819 match self {
4920 Self :: Leaf ( s) => * s,
5021 _ => bug ! ( "expected leaf, got {:?}" , self ) ,
5122 }
5223 }
5324
5425 #[ inline]
55- pub fn unwrap_branch ( & self ) -> & [ ValTree < ' tcx > ] {
26+ fn unwrap_branch ( & self ) -> & [ ty :: Const < ' tcx > ] {
5627 match self {
5728 Self :: Branch ( branch) => & * * branch,
5829 _ => bug ! ( "expected branch, got {:?}" , self ) ,
5930 }
6031 }
6132
62- pub fn try_to_scalar ( & self ) -> Option < Scalar > {
33+ fn try_to_scalar ( & self ) -> Option < Scalar > {
6334 self . try_to_scalar_int ( ) . map ( Scalar :: Int )
6435 }
6536
66- pub fn try_to_scalar_int ( & self ) -> Option < ScalarInt > {
37+ fn try_to_scalar_int ( & self ) -> Option < ScalarInt > {
6738 match self {
6839 Self :: Leaf ( s) => Some ( * s) ,
6940 Self :: Branch ( _) => None ,
7041 }
7142 }
7243
73- pub fn try_to_branch ( & self ) -> Option < & [ ValTree < ' tcx > ] > {
44+ fn try_to_branch ( & self ) -> Option < & [ ty :: Const < ' tcx > ] > {
7445 match self {
7546 Self :: Branch ( branch) => Some ( & * * branch) ,
7647 Self :: Leaf ( _) => None ,
@@ -85,7 +56,13 @@ impl<'tcx> ValTreeKind<'tcx> {
8556/// [dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html#valtrees
8657#[ derive( Copy , Clone , Hash , Eq , PartialEq ) ]
8758#[ derive( HashStable ) ]
88- pub struct ValTree < ' tcx > ( pub ( crate ) Interned < ' tcx , ValTreeKind < ' tcx > > ) ;
59+ pub struct ValTree < ' tcx > ( pub ( crate ) Interned < ' tcx , ty:: ValTreeKind < TyCtxt < ' tcx > > > ) ;
60+
61+ impl < ' tcx > rustc_type_ir:: inherent:: ValTree < TyCtxt < ' tcx > > for ValTree < ' tcx > {
62+ fn kind ( & self ) -> & ty:: ValTreeKind < TyCtxt < ' tcx > > {
63+ & self
64+ }
65+ }
8966
9067impl < ' tcx > ValTree < ' tcx > {
9168 /// Returns the zero-sized valtree: `Branch([])`.
@@ -94,28 +71,33 @@ impl<'tcx> ValTree<'tcx> {
9471 }
9572
9673 pub fn is_zst ( self ) -> bool {
97- matches ! ( * self , ValTreeKind :: Branch ( box [ ] ) )
74+ matches ! ( * self , ty :: ValTreeKind :: Branch ( box [ ] ) )
9875 }
9976
10077 pub fn from_raw_bytes ( tcx : TyCtxt < ' tcx > , bytes : & [ u8 ] ) -> Self {
101- let branches = bytes. iter ( ) . map ( |& b| Self :: from_scalar_int ( tcx, b. into ( ) ) ) ;
78+ let branches = bytes. iter ( ) . map ( |& b| {
79+ ty:: Const :: new_value ( tcx, Self :: from_scalar_int ( tcx, b. into ( ) ) , tcx. types . u8 )
80+ } ) ;
10281 Self :: from_branches ( tcx, branches)
10382 }
10483
105- pub fn from_branches ( tcx : TyCtxt < ' tcx > , branches : impl IntoIterator < Item = Self > ) -> Self {
106- tcx. intern_valtree ( ValTreeKind :: Branch ( branches. into_iter ( ) . collect ( ) ) )
84+ pub fn from_branches (
85+ tcx : TyCtxt < ' tcx > ,
86+ branches : impl IntoIterator < Item = ty:: Const < ' tcx > > ,
87+ ) -> Self {
88+ tcx. intern_valtree ( ty:: ValTreeKind :: Branch ( branches. into_iter ( ) . collect ( ) ) )
10789 }
10890
10991 pub fn from_scalar_int ( tcx : TyCtxt < ' tcx > , i : ScalarInt ) -> Self {
110- tcx. intern_valtree ( ValTreeKind :: Leaf ( i) )
92+ tcx. intern_valtree ( ty :: ValTreeKind :: Leaf ( i) )
11193 }
11294}
11395
11496impl < ' tcx > Deref for ValTree < ' tcx > {
115- type Target = & ' tcx ValTreeKind < ' tcx > ;
97+ type Target = & ' tcx ty :: ValTreeKind < TyCtxt < ' tcx > > ;
11698
11799 #[ inline]
118- fn deref ( & self ) -> & & ' tcx ValTreeKind < ' tcx > {
100+ fn deref ( & self ) -> & & ' tcx ty :: ValTreeKind < TyCtxt < ' tcx > > {
119101 & self . 0 . 0
120102 }
121103}
@@ -192,9 +174,14 @@ impl<'tcx> Value<'tcx> {
192174 _ => return None ,
193175 }
194176
195- Some ( tcx. arena . alloc_from_iter (
196- self . valtree . unwrap_branch ( ) . into_iter ( ) . map ( |v| v. unwrap_leaf ( ) . to_u8 ( ) ) ,
197- ) )
177+ Some (
178+ tcx. arena . alloc_from_iter (
179+ self . valtree
180+ . unwrap_branch ( )
181+ . into_iter ( )
182+ . map ( |ct| ct. to_value ( ) . valtree . unwrap_leaf ( ) . to_u8 ( ) ) ,
183+ ) ,
184+ )
198185 }
199186}
200187
0 commit comments