@@ -19,11 +19,105 @@ use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerEx
19
19
20
20
use rustc:: mir:: interpret:: {
21
21
GlobalId , AllocId ,
22
- ConstValue , Pointer , Scalar , ScalarMaybeUndef ,
22
+ ConstValue , Pointer , Scalar ,
23
23
EvalResult , EvalErrorKind
24
24
} ;
25
25
use super :: { EvalContext , Machine , MemPlace , MPlaceTy , MemoryKind } ;
26
26
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
+
27
121
/// A `Value` represents a single immediate self-contained Rust value.
28
122
///
29
123
/// For optimization of a few very common cases, there is also a representation for a pair of
0 commit comments