@@ -6,8 +6,8 @@ use crate::borrow_check::nll::region_infer::values::LivenessValues;
6
6
use rustc:: infer:: InferCtxt ;
7
7
use rustc:: mir:: visit:: TyContext ;
8
8
use rustc:: mir:: visit:: Visitor ;
9
- use rustc:: mir:: { BasicBlock , BasicBlockData , Location , Body , Place , PlaceBase , Rvalue } ;
10
- use rustc:: mir:: { SourceInfo , Statement , Terminator } ;
9
+ use rustc:: mir:: { BasicBlock , BasicBlockData , Location , Body , Place , PlaceBase , Rvalue , TerminatorKind } ;
10
+ use rustc:: mir:: { Local , SourceInfo , Statement , StatementKind , Terminator } ;
11
11
use rustc:: mir:: UserTypeProjection ;
12
12
use rustc:: ty:: fold:: TypeFoldable ;
13
13
use rustc:: ty:: { self , ClosureSubsts , GeneratorSubsts , RegionVid , Ty } ;
@@ -114,6 +114,17 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> {
114
114
self . location_table
115
115
. start_index ( location. successor_within_block ( ) ) ,
116
116
) ) ;
117
+
118
+ // If there are borrows on this now dead local, we need to record them as `killed`.
119
+ if let StatementKind :: StorageDead ( ref local) = statement. kind {
120
+ record_killed_borrows_for_local (
121
+ all_facts,
122
+ self . borrow_set ,
123
+ self . location_table ,
124
+ local,
125
+ location,
126
+ ) ;
127
+ }
117
128
}
118
129
119
130
self . super_statement ( statement, location) ;
@@ -127,20 +138,7 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> {
127
138
) {
128
139
// When we see `X = ...`, then kill borrows of
129
140
// `(*X).foo` and so forth.
130
- if let Some ( all_facts) = self . all_facts {
131
- if let Place {
132
- base : PlaceBase :: Local ( temp) ,
133
- projection : None ,
134
- } = place {
135
- if let Some ( borrow_indices) = self . borrow_set . local_map . get ( temp) {
136
- all_facts. killed . reserve ( borrow_indices. len ( ) ) ;
137
- for & borrow_index in borrow_indices {
138
- let location_index = self . location_table . mid_index ( location) ;
139
- all_facts. killed . push ( ( borrow_index, location_index) ) ;
140
- }
141
- }
142
- }
143
- }
141
+ self . record_killed_borrows_for_place ( place, location) ;
144
142
145
143
self . super_assign ( place, rvalue, location) ;
146
144
}
@@ -167,6 +165,14 @@ impl<'cg, 'cx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'cx, 'tcx> {
167
165
}
168
166
}
169
167
168
+ // A `Call` terminator's return value can be a local which has borrows,
169
+ // so we need to record those as `killed` as well.
170
+ if let TerminatorKind :: Call { ref destination, .. } = terminator. kind {
171
+ if let Some ( ( place, _) ) = destination {
172
+ self . record_killed_borrows_for_place ( place, location) ;
173
+ }
174
+ }
175
+
170
176
self . super_terminator ( terminator, location) ;
171
177
}
172
178
@@ -201,4 +207,40 @@ impl<'cx, 'cg, 'tcx> ConstraintGeneration<'cx, 'cg, 'tcx> {
201
207
self . liveness_constraints . add_element ( vid, location) ;
202
208
} ) ;
203
209
}
210
+
211
+ /// When recording facts for Polonius, records the borrows on the specified place
212
+ /// as `killed`. For example, when assigning to a local, or on a call's return destination.
213
+ fn record_killed_borrows_for_place ( & mut self , place : & Place < ' tcx > , location : Location ) {
214
+ if let Some ( all_facts) = self . all_facts {
215
+ if let Place {
216
+ base : PlaceBase :: Local ( local) ,
217
+ projection : None ,
218
+ } = place {
219
+ record_killed_borrows_for_local (
220
+ all_facts,
221
+ self . borrow_set ,
222
+ self . location_table ,
223
+ local,
224
+ location,
225
+ ) ;
226
+ }
227
+ }
228
+ }
229
+ }
230
+
231
+ /// When recording facts for Polonius, records the borrows on the specified local as `killed`.
232
+ fn record_killed_borrows_for_local (
233
+ all_facts : & mut AllFacts ,
234
+ borrow_set : & BorrowSet < ' _ > ,
235
+ location_table : & LocationTable ,
236
+ local : & Local ,
237
+ location : Location ,
238
+ ) {
239
+ if let Some ( borrow_indices) = borrow_set. local_map . get ( local) {
240
+ all_facts. killed . reserve ( borrow_indices. len ( ) ) ;
241
+ for & borrow_index in borrow_indices {
242
+ let location_index = location_table. mid_index ( location) ;
243
+ all_facts. killed . push ( ( borrow_index, location_index) ) ;
244
+ }
245
+ }
204
246
}
0 commit comments