8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
+ use rustc:: hir;
11
12
use rustc:: mir:: { BasicBlock , BorrowKind , Location , Lvalue , Mir , Rvalue , Statement , StatementKind } ;
12
13
use rustc:: mir:: transform:: MirSource ;
13
14
use rustc:: mir:: visit:: Visitor ;
15
+ use rustc:: mir:: Lvalue :: Projection ;
16
+ use rustc:: mir:: { LvalueProjection , ProjectionElem } ;
14
17
use rustc:: infer:: InferCtxt ;
15
18
use rustc:: traits:: { self , ObligationCause } ;
16
19
use rustc:: ty:: { self , Ty } ;
@@ -198,6 +201,37 @@ impl<'cx, 'gcx, 'tcx> ConstraintGeneration<'cx, 'gcx, 'tcx> {
198
201
destination_region. to_region_index ( ) ,
199
202
location. successor_within_block ( ) ) ;
200
203
}
204
+
205
+ fn add_reborrow_constraint (
206
+ & mut self ,
207
+ location : Location ,
208
+ borrow_region : ty:: Region < ' tcx > ,
209
+ borrowed_lv : & Lvalue < ' tcx > ,
210
+ ) {
211
+ if let Projection ( ref proj) = * borrowed_lv {
212
+ let LvalueProjection { ref base, ref elem } = * * proj;
213
+
214
+ if let ProjectionElem :: Deref = * elem {
215
+ let tcx = self . infcx . tcx ;
216
+ let base_ty = base. ty ( self . mir , tcx) . to_ty ( tcx) ;
217
+ let base_sty = & base_ty. sty ;
218
+
219
+ if let ty:: TyRef ( base_region, ty:: TypeAndMut { ty : _, mutbl } ) = * base_sty {
220
+ match mutbl {
221
+ hir:: Mutability :: MutImmutable => { } ,
222
+
223
+ hir:: Mutability :: MutMutable => {
224
+ self . add_reborrow_constraint ( location, borrow_region, base) ;
225
+ } ,
226
+ }
227
+
228
+ self . regioncx . add_outlives ( base_region. to_region_index ( ) ,
229
+ borrow_region. to_region_index ( ) ,
230
+ location. successor_within_block ( ) ) ;
231
+ }
232
+ }
233
+ }
234
+ }
201
235
}
202
236
203
237
impl < ' cx , ' gcx , ' tcx > Visitor < ' tcx > for ConstraintGeneration < ' cx , ' gcx , ' tcx > {
@@ -214,6 +248,7 @@ impl<'cx, 'gcx, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cx, 'gcx, 'tcx> {
214
248
if let StatementKind :: Assign ( ref destination_lv, ref rv) = statement. kind {
215
249
if let Rvalue :: Ref ( region, bk, ref borrowed_lv) = * rv {
216
250
self . add_borrow_constraint ( location, destination_lv, region, bk, borrowed_lv) ;
251
+ self . add_reborrow_constraint ( location, region, borrowed_lv) ;
217
252
}
218
253
}
219
254
0 commit comments