@@ -300,11 +300,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
300300 rvalue : & Rvalue < ' tcx > ,
301301 place_layout : TyLayout < ' tcx > ,
302302 source_info : SourceInfo ,
303+ place : & Place < ' tcx > ,
303304 ) -> Option < Const < ' tcx > > {
304305 let span = source_info. span ;
305306 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+ } )
308313 } ,
309314 Rvalue :: Ref ( _, _, ref place) => {
310315 let src = self . eval_place ( place, source_info) ?;
@@ -324,22 +329,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
324329 Ok ( dest. into ( ) )
325330 } )
326331 } ,
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 . sty {
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. sty) ;
340- None
341- }
342- } ,
343332 Rvalue :: NullaryOp ( NullOp :: SizeOf , ty) => {
344333 type_size_of ( self . tcx , self . param_env , ty) . and_then ( |n| Some (
345334 ImmTy :: from_uint (
@@ -626,15 +615,15 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
626615 . ty ( & self . local_decls , self . tcx )
627616 . ty ;
628617 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) {
634623 trace ! ( "checking whether {:?} can be stored to {:?}" , value, local) ;
635624 if self . can_const_prop [ local] {
636625 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 ) ) ;
638627 self . set_const ( local, value) ;
639628
640629 if self . should_const_prop ( ) {
@@ -648,6 +637,18 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
648637 }
649638 }
650639 }
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+ }
651652 }
652653 self . super_statement ( statement, location) ;
653654 }
0 commit comments