@@ -26,7 +26,8 @@ impl<const D: u64> EnumSizeOpt<D> {
2626 ty:: Adt ( adt_def, _substs) if adt_def. is_enum ( ) => {
2727 let p_e = tcx. param_env ( body_did) ;
2828 // FIXME(jknodt) handle error better below
29- let layout = tcx. layout_of ( p_e. and ( ty) ) . unwrap ( ) ;
29+ let layout =
30+ if let Ok ( layout) = tcx. layout_of ( p_e. and ( ty) ) { layout } else { return None } ;
3031 let variants = & layout. variants ;
3132 match variants {
3233 Variants :: Single { .. } => None ,
@@ -84,7 +85,16 @@ impl<const D: u64> EnumSizeOpt<D> {
8485 } else {
8586 let mut data =
8687 vec ! [ 0 ; std:: mem:: size_of:: <usize >( ) * num_variants as usize ] ;
87- data. copy_from_slice ( unsafe { std:: mem:: transmute ( & sizes[ ..] ) } ) ;
88+
89+ let mut curr = 0 ;
90+ for byte in sizes
91+ . iter ( )
92+ . flat_map ( |sz| sz. bytes ( ) . to_ne_bytes ( ) )
93+ . take ( data. len ( ) )
94+ {
95+ data[ curr] = byte;
96+ curr += 1 ;
97+ }
8898 let alloc = interpret:: Allocation :: from_bytes (
8999 data,
90100 tcx. data_layout . ptr_sized_integer ( ) . align ( & tcx. data_layout ) . abi ,
@@ -123,9 +133,9 @@ impl<const D: u64> EnumSizeOpt<D> {
123133 kind : StatementKind :: Assign ( box ( place, rval) ) ,
124134 } ;
125135
126- // FIXME(jknodt) do I need to add a storage live here for this place?
127136 let discr_place = Place {
128- local : patch. new_temp ( tcx. types . usize , span) ,
137+ // How do I get the discriminant type?
138+ local : patch. new_temp ( tcx. types . isize , span) ,
129139 projection : List :: empty ( ) ,
130140 } ;
131141
@@ -155,9 +165,8 @@ impl<const D: u64> EnumSizeOpt<D> {
155165 ) ) ,
156166 } ;
157167
158- // FIXME(jknodt) do I need to add a storage live here for this place?
159168 let dst = Place {
160- local : patch. new_temp ( tcx. mk_mut_ptr ( tcx . types . u8 ) , span) ,
169+ local : patch. new_temp ( tcx. mk_mut_ptr ( ty ) , span) ,
161170 projection : List :: empty ( ) ,
162171 } ;
163172
@@ -169,25 +178,52 @@ impl<const D: u64> EnumSizeOpt<D> {
169178 ) ) ,
170179 } ;
171180
172- // FIXME(jknodt) do I need to add a storage live here for this place?
181+ let dst_cast_ty = tcx. mk_mut_ptr ( tcx. types . u8 ) ;
182+ let dst_cast_place = Place {
183+ local : patch. new_temp ( dst_cast_ty, span) ,
184+ projection : List :: empty ( ) ,
185+ } ;
186+
187+ let dst_cast = Statement {
188+ source_info,
189+ kind : StatementKind :: Assign ( box (
190+ dst_cast_place,
191+ Rvalue :: Cast ( CastKind :: Misc , Operand :: Copy ( dst) , dst_cast_ty) ,
192+ ) ) ,
193+ } ;
194+
173195 let src = Place {
174- local : patch. new_temp ( tcx. mk_imm_ptr ( tcx . types . u8 ) , span) ,
196+ local : patch. new_temp ( tcx. mk_imm_ptr ( ty ) , span) ,
175197 projection : List :: empty ( ) ,
176198 } ;
177199
178200 let src_ptr = Statement {
179201 source_info,
180202 kind : StatementKind :: Assign ( box (
181203 src,
182- Rvalue :: AddressOf ( Mutability :: Mut , * rhs) ,
204+ Rvalue :: AddressOf ( Mutability :: Not , * rhs) ,
205+ ) ) ,
206+ } ;
207+
208+ let src_cast_ty = tcx. mk_imm_ptr ( tcx. types . u8 ) ;
209+ let src_cast_place = Place {
210+ local : patch. new_temp ( src_cast_ty, span) ,
211+ projection : List :: empty ( ) ,
212+ } ;
213+
214+ let src_cast = Statement {
215+ source_info,
216+ kind : StatementKind :: Assign ( box (
217+ src_cast_place,
218+ Rvalue :: Cast ( CastKind :: Misc , Operand :: Copy ( src) , src_cast_ty) ,
183219 ) ) ,
184220 } ;
185221
186222 let copy_bytes = Statement {
187223 source_info,
188224 kind : StatementKind :: CopyNonOverlapping ( box CopyNonOverlapping {
189- src : Operand :: Copy ( src ) ,
190- dst : Operand :: Copy ( src ) ,
225+ src : Operand :: Copy ( src_cast_place ) ,
226+ dst : Operand :: Copy ( dst_cast_place ) ,
191227 count : Operand :: Constant (
192228 box ( Constant {
193229 span,
@@ -211,7 +247,9 @@ impl<const D: u64> EnumSizeOpt<D> {
211247 store_discr,
212248 store_size,
213249 dst_ptr,
250+ dst_cast,
214251 src_ptr,
252+ src_cast,
215253 copy_bytes,
216254 store_dead,
217255 ] ) ;
0 commit comments