@@ -108,13 +108,13 @@ pub enum StackPopCleanup {
108108/// State of a local variable including a memoized layout
109109#[ derive( Clone , PartialEq , Eq ) ]
110110pub struct LocalState < ' tcx , Tag =( ) , Id =AllocId > {
111- pub state : LocalValue < Tag , Id > ,
111+ pub value : LocalValue < Tag , Id > ,
112112 /// Don't modify if `Some`, this is only used to prevent computing the layout twice
113113 pub layout : Cell < Option < TyLayout < ' tcx > > > ,
114114}
115115
116- /// State of a local variable
117- #[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
116+ /// Current value of a local variable
117+ #[ derive( Copy , Clone , PartialEq , Eq , Hash , Debug ) ]
118118pub enum LocalValue < Tag =( ) , Id =AllocId > {
119119 /// This local is not currently alive, and cannot be used at all.
120120 Dead ,
@@ -131,27 +131,13 @@ pub enum LocalValue<Tag=(), Id=AllocId> {
131131 Live ( Operand < Tag , Id > ) ,
132132}
133133
134- impl < Tag : Copy > LocalValue < Tag > {
135- /// The initial value of a local: ZST get "initialized" because they can be read from without
136- /// ever having been written to.
137- fn uninit_local (
138- layout : TyLayout < ' _ >
139- ) -> LocalValue < Tag > {
140- // FIXME: Can we avoid this ZST special case? That would likely require MIR
141- // generation changes.
142- if layout. is_zst ( ) {
143- LocalValue :: Live ( Operand :: Immediate ( Immediate :: Scalar ( Scalar :: zst ( ) . into ( ) ) ) )
144- } else {
145- LocalValue :: Uninitialized
146- }
147- }
148- }
149-
150- impl < ' tcx , Tag : Copy > LocalState < ' tcx , Tag > {
151- pub fn access ( & self ) -> EvalResult < ' tcx , & Operand < Tag > > {
152- match self . state {
153- LocalValue :: Dead | LocalValue :: Uninitialized => err ! ( DeadLocal ) ,
154- LocalValue :: Live ( ref val) => Ok ( val) ,
134+ impl < ' tcx , Tag : Copy + ' static > LocalState < ' tcx , Tag > {
135+ pub fn access ( & self ) -> EvalResult < ' tcx , Operand < Tag > > {
136+ match self . value {
137+ LocalValue :: Dead => err ! ( DeadLocal ) ,
138+ LocalValue :: Uninitialized =>
139+ bug ! ( "The type checker should prevent reading from a never-written local" ) ,
140+ LocalValue :: Live ( val) => Ok ( val) ,
155141 }
156142 }
157143
@@ -160,7 +146,7 @@ impl<'tcx, Tag: Copy> LocalState<'tcx, Tag> {
160146 pub fn access_mut (
161147 & mut self ,
162148 ) -> EvalResult < ' tcx , Result < & mut LocalValue < Tag > , MemPlace < Tag > > > {
163- match self . state {
149+ match self . value {
164150 LocalValue :: Dead => err ! ( DeadLocal ) ,
165151 LocalValue :: Live ( Operand :: Indirect ( mplace) ) => Ok ( Err ( mplace) ) ,
166152 ref mut local @ LocalValue :: Live ( Operand :: Immediate ( _) ) |
@@ -507,13 +493,13 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
507493 if mir. local_decls . len ( ) > 1 {
508494 // Locals are initially uninitialized.
509495 let dummy = LocalState {
510- state : LocalValue :: Uninitialized ,
496+ value : LocalValue :: Uninitialized ,
511497 layout : Cell :: new ( None ) ,
512498 } ;
513499 let mut locals = IndexVec :: from_elem ( dummy, & mir. local_decls ) ;
514500 // Return place is handled specially by the `eval_place` functions, and the
515501 // entry in `locals` should never be used. Make it dead, to be sure.
516- locals[ mir:: RETURN_PLACE ] . state = LocalValue :: Dead ;
502+ locals[ mir:: RETURN_PLACE ] . value = LocalValue :: Dead ;
517503 // Now mark those locals as dead that we do not want to initialize
518504 match self . tcx . describe_def ( instance. def_id ( ) ) {
519505 // statics and constants don't have `Storage*` statements, no need to look for them
@@ -526,31 +512,14 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
526512 match stmt. kind {
527513 StorageLive ( local) |
528514 StorageDead ( local) => {
529- locals[ local] . state = LocalValue :: Dead ;
515+ locals[ local] . value = LocalValue :: Dead ;
530516 }
531517 _ => { }
532518 }
533519 }
534520 }
535521 } ,
536522 }
537- // The remaining locals are uninitialized, fill them with `uninit_local`.
538- // (For ZST this is not a NOP.)
539- for ( idx, local) in locals. iter_enumerated_mut ( ) {
540- match local. state {
541- LocalValue :: Uninitialized => {
542- // This needs to be properly initialized.
543- let ty = self . monomorphize ( mir. local_decls [ idx] . ty ) ?;
544- let layout = self . layout_of ( ty) ?;
545- local. state = LocalValue :: uninit_local ( layout) ;
546- local. layout = Cell :: new ( Some ( layout) ) ;
547- }
548- LocalValue :: Dead => {
549- // Nothing to do
550- }
551- LocalValue :: Live ( _) => bug ! ( "Locals cannot be live yet" ) ,
552- }
553- }
554523 // done
555524 self . frame_mut ( ) . locals = locals;
556525 }
@@ -585,7 +554,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
585554 }
586555 // Deallocate all locals that are backed by an allocation.
587556 for local in frame. locals {
588- self . deallocate_local ( local. state ) ?;
557+ self . deallocate_local ( local. value ) ?;
589558 }
590559 // Validate the return value. Do this after deallocating so that we catch dangling
591560 // references.
@@ -633,10 +602,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
633602 assert ! ( local != mir:: RETURN_PLACE , "Cannot make return place live" ) ;
634603 trace ! ( "{:?} is now live" , local) ;
635604
636- let layout = self . layout_of_local ( self . frame ( ) , local, None ) ?;
637- let local_val = LocalValue :: uninit_local ( layout) ;
605+ let local_val = LocalValue :: Uninitialized ;
638606 // StorageLive *always* kills the value that's currently stored
639- Ok ( mem:: replace ( & mut self . frame_mut ( ) . locals [ local] . state , local_val) )
607+ Ok ( mem:: replace ( & mut self . frame_mut ( ) . locals [ local] . value , local_val) )
640608 }
641609
642610 /// Returns the old value of the local.
@@ -645,7 +613,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
645613 assert ! ( local != mir:: RETURN_PLACE , "Cannot make return place dead" ) ;
646614 trace ! ( "{:?} is now dead" , local) ;
647615
648- mem:: replace ( & mut self . frame_mut ( ) . locals [ local] . state , LocalValue :: Dead )
616+ mem:: replace ( & mut self . frame_mut ( ) . locals [ local] . value , LocalValue :: Dead )
649617 }
650618
651619 pub ( super ) fn deallocate_local (
@@ -698,7 +666,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
698666 }
699667 write ! ( msg, ":" ) . unwrap ( ) ;
700668
701- match self . stack [ frame] . locals [ local] . state {
669+ match self . stack [ frame] . locals [ local] . value {
702670 LocalValue :: Dead => write ! ( msg, " is dead" ) . unwrap ( ) ,
703671 LocalValue :: Uninitialized => write ! ( msg, " is uninitialized" ) . unwrap ( ) ,
704672 LocalValue :: Live ( Operand :: Indirect ( mplace) ) => {
0 commit comments