@@ -108,13 +108,13 @@ pub enum StackPopCleanup {
108
108
/// State of a local variable including a memoized layout
109
109
#[ derive( Clone , PartialEq , Eq ) ]
110
110
pub struct LocalState < ' tcx , Tag =( ) , Id =AllocId > {
111
- pub state : LocalValue < Tag , Id > ,
111
+ pub value : LocalValue < Tag , Id > ,
112
112
/// Don't modify if `Some`, this is only used to prevent computing the layout twice
113
113
pub layout : Cell < Option < TyLayout < ' tcx > > > ,
114
114
}
115
115
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 ) ]
118
118
pub enum LocalValue < Tag =( ) , Id =AllocId > {
119
119
/// This local is not currently alive, and cannot be used at all.
120
120
Dead ,
@@ -131,27 +131,13 @@ pub enum LocalValue<Tag=(), Id=AllocId> {
131
131
Live ( Operand < Tag , Id > ) ,
132
132
}
133
133
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) ,
155
141
}
156
142
}
157
143
@@ -160,7 +146,7 @@ impl<'tcx, Tag: Copy> LocalState<'tcx, Tag> {
160
146
pub fn access_mut (
161
147
& mut self ,
162
148
) -> EvalResult < ' tcx , Result < & mut LocalValue < Tag > , MemPlace < Tag > > > {
163
- match self . state {
149
+ match self . value {
164
150
LocalValue :: Dead => err ! ( DeadLocal ) ,
165
151
LocalValue :: Live ( Operand :: Indirect ( mplace) ) => Ok ( Err ( mplace) ) ,
166
152
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
507
493
if mir. local_decls . len ( ) > 1 {
508
494
// Locals are initially uninitialized.
509
495
let dummy = LocalState {
510
- state : LocalValue :: Uninitialized ,
496
+ value : LocalValue :: Uninitialized ,
511
497
layout : Cell :: new ( None ) ,
512
498
} ;
513
499
let mut locals = IndexVec :: from_elem ( dummy, & mir. local_decls ) ;
514
500
// Return place is handled specially by the `eval_place` functions, and the
515
501
// 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 ;
517
503
// Now mark those locals as dead that we do not want to initialize
518
504
match self . tcx . describe_def ( instance. def_id ( ) ) {
519
505
// 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
526
512
match stmt. kind {
527
513
StorageLive ( local) |
528
514
StorageDead ( local) => {
529
- locals[ local] . state = LocalValue :: Dead ;
515
+ locals[ local] . value = LocalValue :: Dead ;
530
516
}
531
517
_ => { }
532
518
}
533
519
}
534
520
}
535
521
} ,
536
522
}
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
- }
554
523
// done
555
524
self . frame_mut ( ) . locals = locals;
556
525
}
@@ -585,7 +554,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
585
554
}
586
555
// Deallocate all locals that are backed by an allocation.
587
556
for local in frame. locals {
588
- self . deallocate_local ( local. state ) ?;
557
+ self . deallocate_local ( local. value ) ?;
589
558
}
590
559
// Validate the return value. Do this after deallocating so that we catch dangling
591
560
// references.
@@ -633,10 +602,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
633
602
assert ! ( local != mir:: RETURN_PLACE , "Cannot make return place live" ) ;
634
603
trace ! ( "{:?} is now live" , local) ;
635
604
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 ;
638
606
// 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) )
640
608
}
641
609
642
610
/// 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
645
613
assert ! ( local != mir:: RETURN_PLACE , "Cannot make return place dead" ) ;
646
614
trace ! ( "{:?} is now dead" , local) ;
647
615
648
- mem:: replace ( & mut self . frame_mut ( ) . locals [ local] . state , LocalValue :: Dead )
616
+ mem:: replace ( & mut self . frame_mut ( ) . locals [ local] . value , LocalValue :: Dead )
649
617
}
650
618
651
619
pub ( super ) fn deallocate_local (
@@ -698,7 +666,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
698
666
}
699
667
write ! ( msg, ":" ) . unwrap ( ) ;
700
668
701
- match self . stack [ frame] . locals [ local] . state {
669
+ match self . stack [ frame] . locals [ local] . value {
702
670
LocalValue :: Dead => write ! ( msg, " is dead" ) . unwrap ( ) ,
703
671
LocalValue :: Uninitialized => write ! ( msg, " is uninitialized" ) . unwrap ( ) ,
704
672
LocalValue :: Live ( Operand :: Indirect ( mplace) ) => {
0 commit comments