@@ -10,7 +10,7 @@ use rustc::mir::visit::{
1010} ;
1111use rustc:: mir:: {
1212 read_only, AggregateKind , BasicBlock , BinOp , Body , BodyAndCache , ClearCrossCrate , Constant ,
13- Local , LocalDecl , LocalKind , Location , Operand , Place , ReadOnlyBodyAndCache , Rvalue ,
13+ Local , LocalDecl , LocalKind , Location , Operand , Place , PlaceRef , ReadOnlyBodyAndCache , Rvalue ,
1414 SourceInfo , SourceScope , SourceScopeData , Statement , StatementKind , Terminator , TerminatorKind ,
1515 UnOp , RETURN_PLACE ,
1616} ;
@@ -602,20 +602,24 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
602602 // (e.g. for CTFE) it can never happen. But here in const_prop
603603 // unknown data is uninitialized, so if e.g. a function argument is unsized
604604 // and has a reference taken, we get an ICE.
605+ //
606+ // Additionally, to evaluate a Ref into a place to const prop, we must ensure that the
607+ // underlying base data is initialized before we evaluate the rvalue, or we will end up
608+ // propagating an allocation which will never be initialized.
605609 Rvalue :: Ref ( _, _, place_ref) => {
606610 trace ! ( "checking Ref({:?})" , place_ref) ;
607611
608- if let Some ( local) = place_ref. as_local ( ) {
609- let alive = if let LocalValue :: Live ( _) = self . ecx . frame ( ) . locals [ local] . value {
610- true
611- } else {
612- false
613- } ;
612+ let PlaceRef { local, .. } = place_ref. as_ref ( ) ;
614613
615- if !alive {
616- trace ! ( "skipping Ref({:?}) to uninitialized local" , place) ;
617- return None ;
618- }
614+ let alive = if let LocalValue :: Live ( _) = self . ecx . frame ( ) . locals [ * local] . value {
615+ true
616+ } else {
617+ false
618+ } ;
619+
620+ if !alive {
621+ trace ! ( "skipping Ref({:?}) to uninitialized local" , place) ;
622+ return None ;
619623 }
620624 }
621625
0 commit comments