@@ -19,11 +19,105 @@ use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerEx
1919
2020use rustc:: mir:: interpret:: {
2121 GlobalId , AllocId ,
22- ConstValue , Pointer , Scalar , ScalarMaybeUndef ,
22+ ConstValue , Pointer , Scalar ,
2323 EvalResult , EvalErrorKind
2424} ;
2525use super :: { EvalContext , Machine , MemPlace , MPlaceTy , MemoryKind } ;
2626
27+ #[ derive( Clone , Copy , Debug , Eq , PartialEq , Ord , PartialOrd , RustcEncodable , RustcDecodable , Hash ) ]
28+ pub enum ScalarMaybeUndef < Id =AllocId > {
29+ Scalar ( Scalar < Id > ) ,
30+ Undef ,
31+ }
32+
33+ impl From < Scalar > for ScalarMaybeUndef {
34+ #[ inline( always) ]
35+ fn from ( s : Scalar ) -> Self {
36+ ScalarMaybeUndef :: Scalar ( s)
37+ }
38+ }
39+
40+ impl < ' tcx > ScalarMaybeUndef {
41+ #[ inline]
42+ pub fn not_undef ( self ) -> EvalResult < ' static , Scalar > {
43+ match self {
44+ ScalarMaybeUndef :: Scalar ( scalar) => Ok ( scalar) ,
45+ ScalarMaybeUndef :: Undef => err ! ( ReadUndefBytes ( Size :: from_bytes( 0 ) ) ) ,
46+ }
47+ }
48+
49+ #[ inline( always) ]
50+ pub fn to_ptr ( self ) -> EvalResult < ' tcx , Pointer > {
51+ self . not_undef ( ) ?. to_ptr ( )
52+ }
53+
54+ #[ inline( always) ]
55+ pub fn to_bits ( self , target_size : Size ) -> EvalResult < ' tcx , u128 > {
56+ self . not_undef ( ) ?. to_bits ( target_size)
57+ }
58+
59+ #[ inline( always) ]
60+ pub fn to_bool ( self ) -> EvalResult < ' tcx , bool > {
61+ self . not_undef ( ) ?. to_bool ( )
62+ }
63+
64+ #[ inline( always) ]
65+ pub fn to_char ( self ) -> EvalResult < ' tcx , char > {
66+ self . not_undef ( ) ?. to_char ( )
67+ }
68+
69+ #[ inline( always) ]
70+ pub fn to_f32 ( self ) -> EvalResult < ' tcx , f32 > {
71+ self . not_undef ( ) ?. to_f32 ( )
72+ }
73+
74+ #[ inline( always) ]
75+ pub fn to_f64 ( self ) -> EvalResult < ' tcx , f64 > {
76+ self . not_undef ( ) ?. to_f64 ( )
77+ }
78+
79+ #[ inline( always) ]
80+ pub fn to_u8 ( self ) -> EvalResult < ' tcx , u8 > {
81+ self . not_undef ( ) ?. to_u8 ( )
82+ }
83+
84+ #[ inline( always) ]
85+ pub fn to_u32 ( self ) -> EvalResult < ' tcx , u32 > {
86+ self . not_undef ( ) ?. to_u32 ( )
87+ }
88+
89+ #[ inline( always) ]
90+ pub fn to_u64 ( self ) -> EvalResult < ' tcx , u64 > {
91+ self . not_undef ( ) ?. to_u64 ( )
92+ }
93+
94+ #[ inline( always) ]
95+ pub fn to_usize ( self , cx : impl HasDataLayout ) -> EvalResult < ' tcx , u64 > {
96+ self . not_undef ( ) ?. to_usize ( cx)
97+ }
98+
99+ #[ inline( always) ]
100+ pub fn to_i8 ( self ) -> EvalResult < ' tcx , i8 > {
101+ self . not_undef ( ) ?. to_i8 ( )
102+ }
103+
104+ #[ inline( always) ]
105+ pub fn to_i32 ( self ) -> EvalResult < ' tcx , i32 > {
106+ self . not_undef ( ) ?. to_i32 ( )
107+ }
108+
109+ #[ inline( always) ]
110+ pub fn to_i64 ( self ) -> EvalResult < ' tcx , i64 > {
111+ self . not_undef ( ) ?. to_i64 ( )
112+ }
113+
114+ #[ inline( always) ]
115+ pub fn to_isize ( self , cx : impl HasDataLayout ) -> EvalResult < ' tcx , i64 > {
116+ self . not_undef ( ) ?. to_isize ( cx)
117+ }
118+ }
119+
120+
27121/// A `Value` represents a single immediate self-contained Rust value.
28122///
29123/// For optimization of a few very common cases, there is also a representation for a pair of
0 commit comments