11pub use super :: * ;
22
3+ use crate :: dataflow:: generic:: { Results , ResultsRefCursor } ;
34use crate :: dataflow:: BitDenotation ;
4- use crate :: dataflow:: HaveBeenBorrowedLocals ;
5- use crate :: dataflow:: { DataflowResults , DataflowResultsCursor , DataflowResultsRefCursor } ;
5+ use crate :: dataflow:: MaybeBorrowedLocals ;
66use rustc:: mir:: visit:: { NonMutatingUseContext , PlaceContext , Visitor } ;
77use rustc:: mir:: * ;
88use std:: cell:: RefCell ;
@@ -69,22 +69,23 @@ impl<'a, 'tcx> BottomValue for MaybeStorageLive<'a, 'tcx> {
6969 const BOTTOM_VALUE : bool = false ;
7070}
7171
72+ type BorrowedLocalsResults < ' a , ' tcx > = ResultsRefCursor < ' a , ' a , ' tcx , MaybeBorrowedLocals > ;
73+
7274/// Dataflow analysis that determines whether each local requires storage at a
7375/// given location; i.e. whether its storage can go away without being observed.
7476pub struct RequiresStorage < ' mir , ' tcx > {
7577 body : ReadOnlyBodyAndCache < ' mir , ' tcx > ,
76- borrowed_locals :
77- RefCell < DataflowResultsRefCursor < ' mir , ' tcx , HaveBeenBorrowedLocals < ' mir , ' tcx > > > ,
78+ borrowed_locals : RefCell < BorrowedLocalsResults < ' mir , ' tcx > > ,
7879}
7980
8081impl < ' mir , ' tcx : ' mir > RequiresStorage < ' mir , ' tcx > {
8182 pub fn new (
8283 body : ReadOnlyBodyAndCache < ' mir , ' tcx > ,
83- borrowed_locals : & ' mir DataflowResults < ' tcx , HaveBeenBorrowedLocals < ' mir , ' tcx > > ,
84+ borrowed_locals : & ' mir Results < ' tcx , MaybeBorrowedLocals > ,
8485 ) -> Self {
8586 RequiresStorage {
8687 body,
87- borrowed_locals : RefCell :: new ( DataflowResultsCursor :: new ( borrowed_locals , * body) ) ,
88+ borrowed_locals : RefCell :: new ( ResultsRefCursor :: new ( * body, borrowed_locals ) ) ,
8889 }
8990 }
9091
@@ -111,11 +112,12 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
111112 }
112113
113114 fn before_statement_effect ( & self , sets : & mut GenKillSet < Self :: Idx > , loc : Location ) {
114- // If we borrow or assign to a place then it needs storage for that
115- // statement.
116- self . check_for_borrow ( sets, loc) ;
117-
118115 let stmt = & self . body [ loc. block ] . statements [ loc. statement_index ] ;
116+
117+ // If a place is borrowed in a statement, it needs storage for that statement.
118+ self . borrowed_locals . borrow ( ) . analysis ( ) . statement_effect ( sets, stmt, loc) ;
119+
120+ // If a place is assigned to in a statement, it needs storage for that statement.
119121 match stmt. kind {
120122 StatementKind :: StorageDead ( l) => sets. kill ( l) ,
121123 StatementKind :: Assign ( box ( ref place, _) )
@@ -138,12 +140,13 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
138140 }
139141
140142 fn before_terminator_effect ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
141- self . check_for_borrow ( sets , loc) ;
143+ let terminator = self . body [ loc. block ] . terminator ( ) ;
142144
143- if let TerminatorKind :: Call { destination : Some ( ( Place { local, .. } , _) ) , .. } =
144- self . body [ loc. block ] . terminator ( ) . kind
145- {
146- sets. gen ( local) ;
145+ // If a place is borrowed in a terminator, it needs storage for that terminator.
146+ self . borrowed_locals . borrow ( ) . analysis ( ) . terminator_effect ( sets, terminator, loc) ;
147+
148+ if let TerminatorKind :: Call { destination : Some ( ( place, _) ) , .. } = terminator. kind {
149+ sets. gen ( place. local ) ;
147150 }
148151 }
149152
@@ -179,14 +182,6 @@ impl<'mir, 'tcx> RequiresStorage<'mir, 'tcx> {
179182 let mut visitor = MoveVisitor { sets, borrowed_locals : & self . borrowed_locals } ;
180183 visitor. visit_location ( self . body , loc) ;
181184 }
182-
183- /// Gen locals that are newly borrowed. This includes borrowing any part of
184- /// a local (we rely on this behavior of `HaveBeenBorrowedLocals`).
185- fn check_for_borrow ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
186- let mut borrowed_locals = self . borrowed_locals . borrow_mut ( ) ;
187- borrowed_locals. seek ( loc) ;
188- borrowed_locals. each_gen_bit ( |l| sets. gen ( l) ) ;
189- }
190185}
191186
192187impl < ' mir , ' tcx > BottomValue for RequiresStorage < ' mir , ' tcx > {
@@ -195,16 +190,15 @@ impl<'mir, 'tcx> BottomValue for RequiresStorage<'mir, 'tcx> {
195190}
196191
197192struct MoveVisitor < ' a , ' mir , ' tcx > {
198- borrowed_locals :
199- & ' a RefCell < DataflowResultsRefCursor < ' mir , ' tcx , HaveBeenBorrowedLocals < ' mir , ' tcx > > > ,
193+ borrowed_locals : & ' a RefCell < BorrowedLocalsResults < ' mir , ' tcx > > ,
200194 sets : & ' a mut GenKillSet < Local > ,
201195}
202196
203197impl < ' a , ' mir : ' a , ' tcx > Visitor < ' tcx > for MoveVisitor < ' a , ' mir , ' tcx > {
204198 fn visit_local ( & mut self , local : & Local , context : PlaceContext , loc : Location ) {
205199 if PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Move ) == context {
206200 let mut borrowed_locals = self . borrowed_locals . borrow_mut ( ) ;
207- borrowed_locals. seek ( loc) ;
201+ borrowed_locals. seek_before ( loc) ;
208202 if !borrowed_locals. contains ( * local) {
209203 self . sets . kill ( * local) ;
210204 }
0 commit comments