@@ -11,7 +11,7 @@ use rustc::mir::interpret::{
1111} ;
1212use rustc:: mir:: CastKind ;
1313
14- use super :: { InterpCx , Machine , PlaceTy , OpTy , Immediate , FnVal } ;
14+ use super :: { InterpCx , Machine , PlaceTy , OpTy , ImmTy , Immediate , FnVal } ;
1515
1616impl < ' mir , ' tcx , M : Machine < ' mir , ' tcx > > InterpCx < ' mir , ' tcx , M > {
1717 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> {
3737
3838 Misc | Pointer ( PointerCast :: MutToConstPointer ) => {
3939 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) ?;
7442 }
7543
7644 Pointer ( PointerCast :: ReifyFnPointer ) => {
@@ -126,6 +94,43 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
12694 Ok ( ( ) )
12795 }
12896
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+
129134 fn cast_scalar (
130135 & self ,
131136 val : Scalar < M :: PointerTag > ,
0 commit comments