@@ -263,16 +263,29 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
263
263
match guarantor. cat {
264
264
mc:: cat_deref( _, _, mc:: BorrowedPtr ( ..) ) |
265
265
mc:: cat_deref( _, _, mc:: Implicit ( ..) ) => {
266
- if let mc:: NoteUpvarRef ( upvar_id) = cmt. note {
267
- debug ! ( "adjust_upvar_borrow_kind_for_consume: \
268
- setting upvar_id={:?} to by value",
269
- upvar_id) ;
266
+ match cmt. note {
267
+ mc:: NoteUpvarRef ( upvar_id) => {
268
+ debug ! ( "adjust_upvar_borrow_kind_for_consume: \
269
+ setting upvar_id={:?} to by value",
270
+ upvar_id) ;
270
271
271
- // to move out of an upvar, this must be a FnOnce closure
272
- self . adjust_closure_kind ( upvar_id. closure_expr_id , ty:: FnOnceClosureKind ) ;
272
+ // to move out of an upvar, this must be a FnOnce closure
273
+ self . adjust_closure_kind ( upvar_id. closure_expr_id , ty:: FnOnceClosureKind ) ;
273
274
274
- let mut upvar_capture_map = self . fcx . inh . upvar_capture_map . borrow_mut ( ) ;
275
- upvar_capture_map. insert ( upvar_id, ty:: UpvarCapture :: ByValue ) ;
275
+ let mut upvar_capture_map = self . fcx . inh . upvar_capture_map . borrow_mut ( ) ;
276
+ upvar_capture_map. insert ( upvar_id, ty:: UpvarCapture :: ByValue ) ;
277
+ }
278
+ mc:: NoteClosureEnv ( upvar_id) => {
279
+ // we get just a closureenv ref if this is a
280
+ // `move` closure, or if the upvar has already
281
+ // been inferred to by-value. In any case, we
282
+ // must still adjust the kind of the closure
283
+ // to be a FnOnce closure to permit moves out
284
+ // of the environment.
285
+ self . adjust_closure_kind ( upvar_id. closure_expr_id , ty:: FnOnceClosureKind ) ;
286
+ }
287
+ mc:: NoteNone => {
288
+ }
276
289
}
277
290
}
278
291
_ => { }
@@ -297,15 +310,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
297
310
298
311
mc:: cat_deref( base, _, mc:: BorrowedPtr ( ..) ) |
299
312
mc:: cat_deref( base, _, mc:: Implicit ( ..) ) => {
300
- if let mc:: NoteUpvarRef ( upvar_id) = cmt. note {
301
- // if this is an implicit deref of an
302
- // upvar, then we need to modify the
303
- // borrow_kind of the upvar to make sure it
304
- // is inferred to mutable if necessary
305
- let mut upvar_capture_map = self . fcx . inh . upvar_capture_map . borrow_mut ( ) ;
306
- let ub = & mut upvar_capture_map[ upvar_id] ;
307
- self . adjust_upvar_borrow_kind ( upvar_id, ub, ty:: MutBorrow ) ;
308
- } else {
313
+ if !self . try_adjust_upvar_deref ( & cmt. note , ty:: MutBorrow ) {
309
314
// assignment to deref of an `&mut`
310
315
// borrowed pointer implies that the
311
316
// pointer itself must be unique, but not
@@ -339,15 +344,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
339
344
340
345
mc:: cat_deref( base, _, mc:: BorrowedPtr ( ..) ) |
341
346
mc:: cat_deref( base, _, mc:: Implicit ( ..) ) => {
342
- if let mc:: NoteUpvarRef ( upvar_id) = cmt. note {
343
- // if this is an implicit deref of an
344
- // upvar, then we need to modify the
345
- // borrow_kind of the upvar to make sure it
346
- // is inferred to unique if necessary
347
- let mut ub = self . fcx . inh . upvar_capture_map . borrow_mut ( ) ;
348
- let ub = & mut ub[ upvar_id] ;
349
- self . adjust_upvar_borrow_kind ( upvar_id, ub, ty:: UniqueImmBorrow ) ;
350
- } else {
347
+ if !self . try_adjust_upvar_deref ( & cmt. note , ty:: UniqueImmBorrow ) {
351
348
// for a borrowed pointer to be unique, its
352
349
// base must be unique
353
350
self . adjust_upvar_borrow_kind_for_unique ( base) ;
@@ -363,6 +360,48 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
363
360
}
364
361
}
365
362
363
+ fn try_adjust_upvar_deref ( & self ,
364
+ note : & mc:: Note ,
365
+ borrow_kind : ty:: BorrowKind )
366
+ -> bool
367
+ {
368
+ assert ! ( match borrow_kind {
369
+ ty:: MutBorrow => true ,
370
+ ty:: UniqueImmBorrow => true ,
371
+
372
+ // imm borrows never require adjusting any kinds, so we don't wind up here
373
+ ty:: ImmBorrow => false ,
374
+ } ) ;
375
+
376
+ match * note {
377
+ mc:: NoteUpvarRef ( upvar_id) => {
378
+ // if this is an implicit deref of an
379
+ // upvar, then we need to modify the
380
+ // borrow_kind of the upvar to make sure it
381
+ // is inferred to mutable if necessary
382
+ let mut upvar_capture_map = self . fcx . inh . upvar_capture_map . borrow_mut ( ) ;
383
+ let ub = & mut upvar_capture_map[ upvar_id] ;
384
+ self . adjust_upvar_borrow_kind ( upvar_id, ub, borrow_kind) ;
385
+
386
+ // also need to be in an FnMut closure since this is not an ImmBorrow
387
+ self . adjust_closure_kind ( upvar_id. closure_expr_id , ty:: FnMutClosureKind ) ;
388
+
389
+ true
390
+ }
391
+ mc:: NoteClosureEnv ( upvar_id) => {
392
+ // this kind of deref occurs in a `move` closure, or
393
+ // for a by-value upvar; in either case, to mutate an
394
+ // upvar, we need to be an FnMut closure
395
+ self . adjust_closure_kind ( upvar_id. closure_expr_id , ty:: FnMutClosureKind ) ;
396
+
397
+ true
398
+ }
399
+ mc:: NoteNone => {
400
+ false
401
+ }
402
+ }
403
+ }
404
+
366
405
/// We infer the borrow_kind with which to borrow upvars in a stack closure. The borrow_kind
367
406
/// basically follows a lattice of `imm < unique-imm < mut`, moving from left to right as needed
368
407
/// (but never right to left). Here the argument `mutbl` is the borrow_kind that is required by
@@ -374,13 +413,6 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
374
413
debug ! ( "adjust_upvar_borrow_kind(upvar_id={:?}, upvar_capture={:?}, kind={:?})" ,
375
414
upvar_id, upvar_capture, kind) ;
376
415
377
- match kind {
378
- ty:: ImmBorrow => { }
379
- ty:: UniqueImmBorrow | ty:: MutBorrow => {
380
- self . adjust_closure_kind ( upvar_id. closure_expr_id , ty:: FnMutClosureKind ) ;
381
- }
382
- }
383
-
384
416
match * upvar_capture {
385
417
ty:: UpvarCapture :: ByValue => {
386
418
// Upvar is already by-value, the strongest criteria.
0 commit comments