@@ -8,96 +8,107 @@ use primval::PrimVal;
8
8
use memory:: Pointer ;
9
9
10
10
use rustc:: ty:: Ty ;
11
- use syntax:: ast:: { self , IntTy , UintTy } ;
11
+ use syntax:: ast:: { FloatTy , IntTy , UintTy } ;
12
12
13
13
impl < ' a , ' tcx > EvalContext < ' a , ' tcx > {
14
14
pub ( super ) fn cast_primval ( & self , val : PrimVal , ty : Ty < ' tcx > ) -> EvalResult < ' tcx , PrimVal > {
15
- use primval:: PrimVal :: * ;
16
- match val {
17
- Bool ( b) => self . cast_const_int ( b as u64 , ty, false ) ,
18
- F32 ( f) => self . cast_const_float ( f as f64 , ty) ,
19
- F64 ( f) => self . cast_const_float ( f, ty) ,
20
- I8 ( i) => self . cast_signed_int ( i as i64 , ty) ,
21
- I16 ( i) => self . cast_signed_int ( i as i64 , ty) ,
22
- I32 ( i) => self . cast_signed_int ( i as i64 , ty) ,
23
- I64 ( i) => self . cast_signed_int ( i, ty) ,
24
- U8 ( u) => self . cast_const_int ( u as u64 , ty, false ) ,
25
- U16 ( u) => self . cast_const_int ( u as u64 , ty, false ) ,
26
- U32 ( u) => self . cast_const_int ( u as u64 , ty, false ) ,
27
- Char ( c) => self . cast_const_int ( c as u64 , ty, false ) ,
28
- U64 ( u) => self . cast_const_int ( u, ty, false ) ,
29
- FnPtr ( ptr) |
30
- Ptr ( ptr) => self . cast_ptr ( ptr, ty) ,
31
- }
32
- }
15
+ use primval:: PrimValKind :: * ;
16
+ match val. kind {
17
+ F32 => self . cast_float ( val. to_f32 ( ) as f64 , ty) ,
18
+ F64 => self . cast_float ( val. to_f64 ( ) , ty) ,
33
19
34
- fn cast_ptr ( & self , ptr : Pointer , ty : Ty < ' tcx > ) -> EvalResult < ' tcx , PrimVal > {
35
- use primval:: PrimVal :: * ;
36
- match ty. sty {
37
- ty:: TyRef ( ..) |
38
- ty:: TyRawPtr ( _) => Ok ( Ptr ( ptr) ) ,
39
- ty:: TyFnPtr ( _) => Ok ( FnPtr ( ptr) ) ,
40
- ty:: TyInt ( IntTy :: I8 ) => Ok ( I8 ( ptr. to_int ( ) ? as i8 ) ) ,
41
- ty:: TyInt ( IntTy :: I16 ) => Ok ( I16 ( ptr. to_int ( ) ? as i16 ) ) ,
42
- ty:: TyInt ( IntTy :: I32 ) => Ok ( I32 ( ptr. to_int ( ) ? as i32 ) ) ,
43
- ty:: TyInt ( IntTy :: I64 ) => Ok ( I64 ( ptr. to_int ( ) ? as i64 ) ) ,
44
- ty:: TyUint ( UintTy :: U8 ) => Ok ( U8 ( ptr. to_int ( ) ? as u8 ) ) ,
45
- ty:: TyUint ( UintTy :: U16 ) => Ok ( U16 ( ptr. to_int ( ) ? as u16 ) ) ,
46
- ty:: TyUint ( UintTy :: U32 ) => Ok ( U32 ( ptr. to_int ( ) ? as u32 ) ) ,
47
- ty:: TyUint ( UintTy :: U64 ) => Ok ( U64 ( ptr. to_int ( ) ? as u64 ) ) ,
48
- _ => Err ( EvalError :: Unimplemented ( format ! ( "ptr to {:?} cast" , ty) ) ) ,
20
+ I8 | I16 | I32 | I64 => self . cast_signed_int ( val. bits as i64 , ty) ,
21
+
22
+ Bool | Char | U8 | U16 | U32 | U64 => self . cast_int ( val. bits , ty, false ) ,
23
+
24
+ FnPtr ( alloc) | Ptr ( alloc) => {
25
+ let ptr = Pointer :: new ( alloc, val. bits as usize ) ;
26
+ self . cast_ptr ( ptr, ty)
27
+ }
49
28
}
50
29
}
51
30
52
31
fn cast_signed_int ( & self , val : i64 , ty : ty:: Ty < ' tcx > ) -> EvalResult < ' tcx , PrimVal > {
53
- self . cast_const_int ( val as u64 , ty, val < 0 )
32
+ self . cast_int ( val as u64 , ty, val < 0 )
54
33
}
55
34
56
- fn cast_const_int ( & self , v : u64 , ty : ty:: Ty < ' tcx > , negative : bool ) -> EvalResult < ' tcx , PrimVal > {
57
- use primval:: PrimVal :: * ;
35
+ fn cast_int ( & self , v : u64 , ty : ty:: Ty < ' tcx > , negative : bool ) -> EvalResult < ' tcx , PrimVal > {
36
+ use primval:: PrimValKind :: * ;
37
+ use rustc:: ty:: TypeVariants :: * ;
58
38
match ty. sty {
59
- ty:: TyBool if v == 0 => Ok ( Bool ( false ) ) ,
60
- ty:: TyBool if v == 1 => Ok ( Bool ( true ) ) ,
61
- ty:: TyBool => Err ( EvalError :: InvalidBool ) ,
62
- ty:: TyInt ( ast:: IntTy :: I8 ) => Ok ( I8 ( v as i64 as i8 ) ) ,
63
- ty:: TyInt ( ast:: IntTy :: I16 ) => Ok ( I16 ( v as i64 as i16 ) ) ,
64
- ty:: TyInt ( ast:: IntTy :: I32 ) => Ok ( I32 ( v as i64 as i32 ) ) ,
65
- ty:: TyInt ( ast:: IntTy :: I64 ) => Ok ( I64 ( v as i64 ) ) ,
66
- ty:: TyInt ( ast:: IntTy :: Is ) => {
39
+ TyBool if v == 0 => Ok ( PrimVal :: from_bool ( false ) ) ,
40
+ TyBool if v == 1 => Ok ( PrimVal :: from_bool ( true ) ) ,
41
+ TyBool => Err ( EvalError :: InvalidBool ) ,
42
+
43
+ TyInt ( IntTy :: I8 ) => Ok ( PrimVal :: new ( v as i64 as i8 as u64 , I8 ) ) ,
44
+ TyInt ( IntTy :: I16 ) => Ok ( PrimVal :: new ( v as i64 as i16 as u64 , I16 ) ) ,
45
+ TyInt ( IntTy :: I32 ) => Ok ( PrimVal :: new ( v as i64 as i32 as u64 , I32 ) ) ,
46
+ TyInt ( IntTy :: I64 ) => Ok ( PrimVal :: new ( v as i64 as i64 as u64 , I64 ) ) ,
47
+
48
+ TyUint ( UintTy :: U8 ) => Ok ( PrimVal :: new ( v as u8 as u64 , U8 ) ) ,
49
+ TyUint ( UintTy :: U16 ) => Ok ( PrimVal :: new ( v as u16 as u64 , U16 ) ) ,
50
+ TyUint ( UintTy :: U32 ) => Ok ( PrimVal :: new ( v as u32 as u64 , U32 ) ) ,
51
+ TyUint ( UintTy :: U64 ) => Ok ( PrimVal :: new ( v, U64 ) ) ,
52
+
53
+ TyInt ( IntTy :: Is ) => {
67
54
let int_ty = self . tcx . sess . target . int_type ;
68
55
let ty = self . tcx . mk_mach_int ( int_ty) ;
69
- self . cast_const_int ( v, ty, negative)
70
- } ,
71
- ty:: TyUint ( ast:: UintTy :: U8 ) => Ok ( U8 ( v as u8 ) ) ,
72
- ty:: TyUint ( ast:: UintTy :: U16 ) => Ok ( U16 ( v as u16 ) ) ,
73
- ty:: TyUint ( ast:: UintTy :: U32 ) => Ok ( U32 ( v as u32 ) ) ,
74
- ty:: TyUint ( ast:: UintTy :: U64 ) => Ok ( U64 ( v) ) ,
75
- ty:: TyUint ( ast:: UintTy :: Us ) => {
56
+ self . cast_int ( v, ty, negative)
57
+ }
58
+
59
+ TyUint ( UintTy :: Us ) => {
76
60
let uint_ty = self . tcx . sess . target . uint_type ;
77
61
let ty = self . tcx . mk_mach_uint ( uint_ty) ;
78
- self . cast_const_int ( v, ty, negative)
79
- } ,
80
- ty:: TyFloat ( ast:: FloatTy :: F64 ) if negative => Ok ( F64 ( v as i64 as f64 ) ) ,
81
- ty:: TyFloat ( ast:: FloatTy :: F64 ) => Ok ( F64 ( v as f64 ) ) ,
82
- ty:: TyFloat ( ast:: FloatTy :: F32 ) if negative => Ok ( F32 ( v as i64 as f32 ) ) ,
83
- ty:: TyFloat ( ast:: FloatTy :: F32 ) => Ok ( F32 ( v as f32 ) ) ,
84
- ty:: TyRawPtr ( _) => Ok ( Ptr ( Pointer :: from_int ( v as usize ) ) ) ,
85
- ty:: TyChar if v as u8 as u64 == v => Ok ( Char ( v as u8 as char ) ) ,
86
- ty:: TyChar => Err ( EvalError :: InvalidChar ( v) ) ,
62
+ self . cast_int ( v, ty, negative)
63
+ }
64
+
65
+ TyFloat ( FloatTy :: F64 ) if negative => Ok ( PrimVal :: from_f64 ( v as i64 as f64 ) ) ,
66
+ TyFloat ( FloatTy :: F64 ) => Ok ( PrimVal :: from_f64 ( v as f64 ) ) ,
67
+ TyFloat ( FloatTy :: F32 ) if negative => Ok ( PrimVal :: from_f32 ( v as i64 as f32 ) ) ,
68
+ TyFloat ( FloatTy :: F32 ) => Ok ( PrimVal :: from_f32 ( v as f32 ) ) ,
69
+
70
+ TyChar if v as u8 as u64 == v => Ok ( PrimVal :: new ( v, Char ) ) ,
71
+ TyChar => Err ( EvalError :: InvalidChar ( v) ) ,
72
+
73
+ TyRawPtr ( _) => Ok ( PrimVal :: from_ptr ( Pointer :: from_int ( v as usize ) ) ) ,
74
+
87
75
_ => Err ( EvalError :: Unimplemented ( format ! ( "int to {:?} cast" , ty) ) ) ,
88
76
}
89
77
}
90
78
91
- fn cast_const_float ( & self , val : f64 , ty : Ty < ' tcx > ) -> EvalResult < ' tcx , PrimVal > {
92
- use primval :: PrimVal :: * ;
79
+ fn cast_float ( & self , val : f64 , ty : Ty < ' tcx > ) -> EvalResult < ' tcx , PrimVal > {
80
+ use rustc :: ty :: TypeVariants :: * ;
93
81
match ty. sty {
94
- // casting negative floats to unsigned integers yields zero
95
- ty:: TyUint ( _) if val < 0.0 => self . cast_const_int ( 0 , ty, false ) ,
96
- ty:: TyInt ( _) if val < 0.0 => self . cast_const_int ( val as i64 as u64 , ty, true ) ,
97
- ty:: TyInt ( _) | ty:: TyUint ( _) => self . cast_const_int ( val as u64 , ty, false ) ,
98
- ty:: TyFloat ( ast:: FloatTy :: F64 ) => Ok ( F64 ( val) ) ,
99
- ty:: TyFloat ( ast:: FloatTy :: F32 ) => Ok ( F32 ( val as f32 ) ) ,
82
+ // Casting negative floats to unsigned integers yields zero.
83
+ TyUint ( _) if val < 0.0 => self . cast_int ( 0 , ty, false ) ,
84
+ TyInt ( _) if val < 0.0 => self . cast_int ( val as i64 as u64 , ty, true ) ,
85
+
86
+ TyInt ( _) | ty:: TyUint ( _) => self . cast_int ( val as u64 , ty, false ) ,
87
+
88
+ TyFloat ( FloatTy :: F64 ) => Ok ( PrimVal :: from_f64 ( val) ) ,
89
+ TyFloat ( FloatTy :: F32 ) => Ok ( PrimVal :: from_f32 ( val as f32 ) ) ,
100
90
_ => Err ( EvalError :: Unimplemented ( format ! ( "float to {:?} cast" , ty) ) ) ,
101
91
}
102
92
}
93
+
94
+ fn cast_ptr ( & self , ptr : Pointer , ty : Ty < ' tcx > ) -> EvalResult < ' tcx , PrimVal > {
95
+ use primval:: PrimValKind :: * ;
96
+ use rustc:: ty:: TypeVariants :: * ;
97
+ match ty. sty {
98
+ TyRef ( ..) | TyRawPtr ( _) => Ok ( PrimVal :: from_ptr ( ptr) ) ,
99
+ TyFnPtr ( _) => Ok ( PrimVal :: from_fn_ptr ( ptr) ) ,
100
+
101
+ TyInt ( IntTy :: I8 ) => Ok ( PrimVal :: new ( ptr. to_int ( ) ? as u64 , I8 ) ) ,
102
+ TyInt ( IntTy :: I16 ) => Ok ( PrimVal :: new ( ptr. to_int ( ) ? as u64 , I16 ) ) ,
103
+ TyInt ( IntTy :: I32 ) => Ok ( PrimVal :: new ( ptr. to_int ( ) ? as u64 , I32 ) ) ,
104
+ TyInt ( IntTy :: I64 ) => Ok ( PrimVal :: new ( ptr. to_int ( ) ? as u64 , I64 ) ) ,
105
+
106
+ TyUint ( UintTy :: U8 ) => Ok ( PrimVal :: new ( ptr. to_int ( ) ? as u64 , U8 ) ) ,
107
+ TyUint ( UintTy :: U16 ) => Ok ( PrimVal :: new ( ptr. to_int ( ) ? as u64 , U16 ) ) ,
108
+ TyUint ( UintTy :: U32 ) => Ok ( PrimVal :: new ( ptr. to_int ( ) ? as u64 , U32 ) ) ,
109
+ TyUint ( UintTy :: U64 ) => Ok ( PrimVal :: new ( ptr. to_int ( ) ? as u64 , U64 ) ) ,
110
+
111
+ _ => Err ( EvalError :: Unimplemented ( format ! ( "ptr to {:?} cast" , ty) ) ) ,
112
+ }
113
+ }
103
114
}
0 commit comments