@@ -11,7 +11,7 @@ use rustc::mir::interpret::{
11
11
} ;
12
12
use rustc:: mir:: CastKind ;
13
13
14
- use super :: { InterpCx , Machine , PlaceTy , OpTy , Immediate , FnVal } ;
14
+ use super :: { InterpCx , Machine , PlaceTy , OpTy , ImmTy , Immediate , FnVal } ;
15
15
16
16
impl < ' mir , ' tcx , M : Machine < ' mir , ' tcx > > InterpCx < ' mir , ' tcx , M > {
17
17
fn type_is_fat_ptr ( & self , ty : Ty < ' tcx > ) -> bool {
@@ -37,40 +37,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
37
37
38
38
Misc | Pointer ( PointerCast :: MutToConstPointer ) => {
39
39
let src = self . read_immediate ( src) ?;
40
-
41
- if self . type_is_fat_ptr ( src. layout . ty ) {
42
- match ( * src, self . type_is_fat_ptr ( dest. layout . ty ) ) {
43
- // pointers to extern types
44
- ( Immediate :: Scalar ( _) , _) |
45
- // slices and trait objects to other slices/trait objects
46
- ( Immediate :: ScalarPair ( ..) , true ) => {
47
- // No change to immediate
48
- self . write_immediate ( * src, dest) ?;
49
- }
50
- // slices and trait objects to thin pointers (dropping the metadata)
51
- ( Immediate :: ScalarPair ( data, _) , false ) => {
52
- self . write_scalar ( data, dest) ?;
53
- }
54
- }
55
- } else {
56
- match src. layout . variants {
57
- layout:: Variants :: Single { index } => {
58
- if let Some ( discr) =
59
- src. layout . ty . discriminant_for_variant ( * self . tcx , index)
60
- {
61
- // Cast from a univariant enum
62
- assert ! ( src. layout. is_zst( ) ) ;
63
- return self . write_scalar (
64
- Scalar :: from_uint ( discr. val , dest. layout . size ) ,
65
- dest) ;
66
- }
67
- }
68
- layout:: Variants :: Multiple { .. } => { } ,
69
- }
70
-
71
- let dest_val = self . cast_scalar ( src. to_scalar ( ) ?, src. layout , dest. layout ) ?;
72
- self . write_scalar ( dest_val, dest) ?;
73
- }
40
+ let res = self . cast_immediate ( src, dest. layout ) ?;
41
+ self . write_immediate ( res, dest) ?;
74
42
}
75
43
76
44
Pointer ( PointerCast :: ReifyFnPointer ) => {
@@ -126,6 +94,43 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
126
94
Ok ( ( ) )
127
95
}
128
96
97
+ fn cast_immediate (
98
+ & self ,
99
+ src : ImmTy < ' tcx , M :: PointerTag > ,
100
+ dest_layout : TyLayout < ' tcx > ,
101
+ ) -> InterpResult < ' tcx , Immediate < M :: PointerTag > > {
102
+ if self . type_is_fat_ptr ( src. layout . ty ) {
103
+ return match ( * src, self . type_is_fat_ptr ( dest_layout. ty ) ) {
104
+ // pointers to extern types
105
+ ( Immediate :: Scalar ( _) , _) |
106
+ // slices and trait objects to other slices/trait objects
107
+ ( Immediate :: ScalarPair ( ..) , true ) => {
108
+ // No change to immediate
109
+ Ok ( * src)
110
+ }
111
+ // slices and trait objects to thin pointers (dropping the metadata)
112
+ ( Immediate :: ScalarPair ( data, _) , false ) => {
113
+ Ok ( data. into ( ) )
114
+ }
115
+ } ;
116
+ } else {
117
+ match src. layout . variants {
118
+ layout:: Variants :: Single { index } => {
119
+ if let Some ( discr) =
120
+ src. layout . ty . discriminant_for_variant ( * self . tcx , index)
121
+ {
122
+ // Cast from a univariant enum
123
+ assert ! ( src. layout. is_zst( ) ) ;
124
+ return Ok ( Scalar :: from_uint ( discr. val , dest_layout. size ) . into ( ) ) ;
125
+ }
126
+ }
127
+ layout:: Variants :: Multiple { .. } => { } ,
128
+ }
129
+
130
+ return Ok ( self . cast_scalar ( src. to_scalar ( ) ?, src. layout , dest_layout) ?. into ( ) ) ;
131
+ }
132
+ }
133
+
129
134
fn cast_scalar (
130
135
& self ,
131
136
val : Scalar < M :: PointerTag > ,
0 commit comments