@@ -300,11 +300,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
300
300
rvalue : & Rvalue < ' tcx > ,
301
301
place_layout : TyLayout < ' tcx > ,
302
302
source_info : SourceInfo ,
303
+ place : & Place < ' tcx > ,
303
304
) -> Option < Const < ' tcx > > {
304
305
let span = source_info. span ;
305
306
match * rvalue {
306
- Rvalue :: Use ( ref op) => {
307
- self . eval_operand ( op, source_info)
307
+ Rvalue :: Use ( _) |
308
+ Rvalue :: Len ( _) => {
309
+ self . use_ecx ( source_info, |this| {
310
+ this. ecx . eval_rvalue_into_place ( rvalue, place) ?;
311
+ this. ecx . eval_place_to_op ( place, Some ( place_layout) )
312
+ } )
308
313
} ,
309
314
Rvalue :: Ref ( _, _, ref place) => {
310
315
let src = self . eval_place ( place, source_info) ?;
@@ -324,22 +329,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
324
329
Ok ( dest. into ( ) )
325
330
} )
326
331
} ,
327
- Rvalue :: Len ( ref place) => {
328
- let place = self . eval_place ( & place, source_info) ?;
329
- let mplace = place. try_as_mplace ( ) . ok ( ) ?;
330
-
331
- if let ty:: Slice ( _) = mplace. layout . ty . kind {
332
- let len = mplace. meta . unwrap ( ) . to_usize ( & self . ecx ) . unwrap ( ) ;
333
-
334
- Some ( ImmTy :: from_uint (
335
- len,
336
- self . tcx . layout_of ( self . param_env . and ( self . tcx . types . usize ) ) . ok ( ) ?,
337
- ) . into ( ) )
338
- } else {
339
- trace ! ( "not slice: {:?}" , mplace. layout. ty. kind) ;
340
- None
341
- }
342
- } ,
343
332
Rvalue :: NullaryOp ( NullOp :: SizeOf , ty) => {
344
333
type_size_of ( self . tcx , self . param_env , ty) . and_then ( |n| Some (
345
334
ImmTy :: from_uint (
@@ -626,15 +615,15 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
626
615
. ty ( & self . local_decls , self . tcx )
627
616
. ty ;
628
617
if let Ok ( place_layout) = self . tcx . layout_of ( self . param_env . and ( place_ty) ) {
629
- if let Some ( value ) = self . const_prop ( rval , place_layout , statement . source_info ) {
630
- if let Place {
631
- base : PlaceBase :: Local ( local ) ,
632
- projection : box [ ] ,
633
- } = * place {
618
+ if let Place {
619
+ base : PlaceBase :: Local ( local ) ,
620
+ projection : box [ ] ,
621
+ } = * place {
622
+ if let Some ( value ) = self . const_prop ( rval , place_layout , statement . source_info , place) {
634
623
trace ! ( "checking whether {:?} can be stored to {:?}" , value, local) ;
635
624
if self . can_const_prop [ local] {
636
625
trace ! ( "storing {:?} to {:?}" , value, local) ;
637
- assert ! ( self . get_const( local) . is_none( ) ) ;
626
+ assert ! ( self . get_const( local) . is_none( ) || self . get_const ( local ) == Some ( value ) ) ;
638
627
self . set_const ( local, value) ;
639
628
640
629
if self . should_const_prop ( ) {
@@ -648,6 +637,18 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
648
637
}
649
638
}
650
639
}
640
+ } else if let StatementKind :: StorageLive ( local) = statement. kind {
641
+ if self . can_const_prop [ local] {
642
+ let frame = self . ecx . frame_mut ( ) ;
643
+
644
+ frame. locals [ local] . value = LocalValue :: Uninitialized ;
645
+ }
646
+ } else if let StatementKind :: StorageDead ( local) = statement. kind {
647
+ if self . can_const_prop [ local] {
648
+ let frame = self . ecx . frame_mut ( ) ;
649
+
650
+ frame. locals [ local] . value = LocalValue :: Dead ;
651
+ }
651
652
}
652
653
self . super_statement ( statement, location) ;
653
654
}
0 commit comments