@@ -263,16 +263,29 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
263263 match guarantor. cat {
264264 mc:: cat_deref( _, _, mc:: BorrowedPtr ( ..) ) |
265265 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) ;
270271
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 ) ;
273274
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+ }
276289 }
277290 }
278291 _ => { }
@@ -297,15 +310,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
297310
298311 mc:: cat_deref( base, _, mc:: BorrowedPtr ( ..) ) |
299312 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 ) {
309314 // assignment to deref of an `&mut`
310315 // borrowed pointer implies that the
311316 // pointer itself must be unique, but not
@@ -339,15 +344,7 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
339344
340345 mc:: cat_deref( base, _, mc:: BorrowedPtr ( ..) ) |
341346 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 ) {
351348 // for a borrowed pointer to be unique, its
352349 // base must be unique
353350 self . adjust_upvar_borrow_kind_for_unique ( base) ;
@@ -363,6 +360,48 @@ impl<'a,'tcx> AdjustBorrowKind<'a,'tcx> {
363360 }
364361 }
365362
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+
366405 /// We infer the borrow_kind with which to borrow upvars in a stack closure. The borrow_kind
367406 /// basically follows a lattice of `imm < unique-imm < mut`, moving from left to right as needed
368407 /// (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> {
374413 debug ! ( "adjust_upvar_borrow_kind(upvar_id={:?}, upvar_capture={:?}, kind={:?})" ,
375414 upvar_id, upvar_capture, kind) ;
376415
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-
384416 match * upvar_capture {
385417 ty:: UpvarCapture :: ByValue => {
386418 // Upvar is already by-value, the strongest criteria.
0 commit comments