@@ -109,15 +109,13 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
109
109
assert_eq ! ( 1 , self . body. arg_count) ;
110
110
}
111
111
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.
116
115
self . check_for_borrow ( sets, loc) ;
117
116
118
117
let stmt = & self . body [ loc. block ] . statements [ loc. statement_index ] ;
119
118
match stmt. kind {
120
- StatementKind :: StorageLive ( l) => sets. gen ( l) ,
121
119
StatementKind :: StorageDead ( l) => sets. kill ( l) ,
122
120
StatementKind :: Assign ( box( ref place, _) )
123
121
| StatementKind :: SetDiscriminant { box ref place, .. } => {
@@ -136,11 +134,35 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
136
134
}
137
135
}
138
136
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.
142
140
self . check_for_move ( sets, loc) ;
141
+ }
142
+
143
+ fn before_terminator_effect ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
143
144
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) ;
144
166
}
145
167
146
168
fn propagate_call_return (
0 commit comments