@@ -10,7 +10,7 @@ use rustc::mir::visit::{
10
10
} ;
11
11
use rustc:: mir:: {
12
12
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 ,
14
14
SourceInfo , SourceScope , SourceScopeData , Statement , StatementKind , Terminator , TerminatorKind ,
15
15
UnOp , RETURN_PLACE ,
16
16
} ;
@@ -602,20 +602,24 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
602
602
// (e.g. for CTFE) it can never happen. But here in const_prop
603
603
// unknown data is uninitialized, so if e.g. a function argument is unsized
604
604
// 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.
605
609
Rvalue :: Ref ( _, _, place_ref) => {
606
610
trace ! ( "checking Ref({:?})" , place_ref) ;
607
611
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 ( ) ;
614
613
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 ;
619
623
}
620
624
}
621
625
0 commit comments