@@ -109,15 +109,13 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
109109 assert_eq ! ( 1 , self . body. arg_count) ;
110110 }
111111
112- fn statement_effect ( & self ,
113- sets : & mut GenKillSet < Local > ,
114- loc : Location ) {
115- self . check_for_move ( sets, loc) ;
112+ fn before_statement_effect ( & self , sets : & mut GenKillSet < Self :: Idx > , loc : Location ) {
113+ // If we borrow or assign to a place then it needs storage for that
114+ // statement.
116115 self . check_for_borrow ( sets, loc) ;
117116
118117 let stmt = & self . body [ loc. block ] . statements [ loc. statement_index ] ;
119118 match stmt. kind {
120- StatementKind :: StorageLive ( l) => sets. gen ( l) ,
121119 StatementKind :: StorageDead ( l) => sets. kill ( l) ,
122120 StatementKind :: Assign ( box( ref place, _) )
123121 | StatementKind :: SetDiscriminant { box ref place, .. } => {
@@ -136,11 +134,35 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
136134 }
137135 }
138136
139- fn terminator_effect ( & self ,
140- sets : & mut GenKillSet < Local > ,
141- loc : Location ) {
137+ fn statement_effect ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
138+ // If we move from a place then only stops needing storage *after*
139+ // that statement.
142140 self . check_for_move ( sets, loc) ;
141+ }
142+
143+ fn before_terminator_effect ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
143144 self . check_for_borrow ( sets, loc) ;
145+
146+ if let TerminatorKind :: Call {
147+ destination : Some ( ( Place { base : PlaceBase :: Local ( local) , .. } , _) ) ,
148+ ..
149+ } = self . body [ loc. block ] . terminator ( ) . kind {
150+ sets. gen ( local) ;
151+ }
152+ }
153+
154+ fn terminator_effect ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
155+ // For call terminators the destination requires storage for the call
156+ // and after the call returns successfully, but not after a panic.
157+ // Since `propagate_call_unwind` doesn't exist, we have to kill the
158+ // destination here, and then gen it again in `propagate_call_return`.
159+ if let TerminatorKind :: Call {
160+ destination : Some ( ( Place { base : PlaceBase :: Local ( local) , projection : box [ ] } , _) ) ,
161+ ..
162+ } = self . body [ loc. block ] . terminator ( ) . kind {
163+ sets. kill ( local) ;
164+ }
165+ self . check_for_move ( sets, loc) ;
144166 }
145167
146168 fn propagate_call_return (
0 commit comments