@@ -44,6 +44,8 @@ use rustc_middle::ty::{self, Ty, TyCtxt, UpvarSubsts};
44
44
use rustc_span:: sym;
45
45
use rustc_span:: { Span , Symbol } ;
46
46
47
+ use std:: env;
48
+
47
49
/// Describe the relationship between the paths of two places
48
50
/// eg:
49
51
/// - `foo` is ancestor of `foo.bar.baz`
@@ -123,10 +125,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
123
125
} ;
124
126
125
127
let local_def_id = closure_def_id. expect_local ( ) ;
126
-
127
128
let mut capture_information: FxIndexMap < Place < ' tcx > , ty:: CaptureInfo < ' tcx > > =
128
129
Default :: default ( ) ;
129
- if !self . tcx . features ( ) . capture_disjoint_fields {
130
+
131
+ if !self . tcx . features ( ) . capture_disjoint_fields && env:: var ( "SG_NEW" ) . is_err ( ) {
130
132
if let Some ( upvars) = self . tcx . upvars_mentioned ( closure_def_id) {
131
133
for ( & var_hir_id, _) in upvars. iter ( ) {
132
134
let place = self . place_for_root_variable ( local_def_id, var_hir_id) ;
@@ -238,8 +240,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
238
240
let capture = captured_place. info . capture_kind ;
239
241
240
242
debug ! (
241
- "place={:?} upvar_ty={:?} capture={:?}" ,
242
- captured_place. place, upvar_ty, capture
243
+ "final_upvar_tys: place={:?} upvar_ty={:?} capture={:?}, mutability={:?}" ,
244
+ captured_place. place,
245
+ upvar_ty,
246
+ capture,
247
+ self . determine_mutability( & captured_place. place) ,
243
248
) ;
244
249
245
250
match capture {
@@ -391,7 +396,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
391
396
392
397
let min_cap_list = match root_var_min_capture_list. get_mut ( & var_hir_id) {
393
398
None => {
394
- let min_cap_list = vec ! [ ty:: CapturedPlace { place: place, info: capture_info } ] ;
399
+ let mutability = self . determine_mutability ( & place) ;
400
+ let min_cap_list =
401
+ vec ! [ ty:: CapturedPlace { place, info: capture_info, mutability } ] ;
395
402
root_var_min_capture_list. insert ( var_hir_id, min_cap_list) ;
396
403
continue ;
397
404
}
@@ -445,8 +452,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
445
452
446
453
// Only need to insert when we don't have an ancestor in the existing min capture list
447
454
if !ancestor_found {
455
+ let mutability = self . determine_mutability ( & place) ;
448
456
let captured_place =
449
- ty:: CapturedPlace { place : place . clone ( ) , info : updated_capture_info } ;
457
+ ty:: CapturedPlace { place, info : updated_capture_info, mutability } ;
450
458
min_cap_list. push ( captured_place) ;
451
459
}
452
460
}
@@ -542,6 +550,49 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
542
550
}
543
551
}
544
552
}
553
+
554
+ /// A place is mutable if
555
+ /// 1. Projections don't include a Deref of an immut-borrow, **and**
556
+ /// 2. PlaceBase is mut or projections include a Deref of a mut-borrow.
557
+ fn determine_mutability ( & self , place : & Place < ' tcx > ) -> hir:: Mutability {
558
+ if place. deref_tys ( ) . any ( ty:: TyS :: is_unsafe_ptr) {
559
+ // Raw pointers don't inherit mutability.
560
+ return hir:: Mutability :: Not ;
561
+ }
562
+
563
+ let var_hir_id = match place. base {
564
+ PlaceBase :: Upvar ( upvar_id) => upvar_id. var_path . hir_id ,
565
+ _ => unreachable ! ( ) ,
566
+ } ;
567
+
568
+ let bm = * self
569
+ . typeck_results
570
+ . borrow ( )
571
+ . pat_binding_modes ( )
572
+ . get ( var_hir_id)
573
+ . expect ( "missing binding mode" ) ;
574
+
575
+ let mut is_mutbl = match bm {
576
+ ty:: BindByValue ( mutability) => mutability,
577
+ ty:: BindByReference ( _) => hir:: Mutability :: Not ,
578
+ } ;
579
+
580
+ for pointer_ty in place. deref_tys ( ) {
581
+ match pointer_ty. kind ( ) {
582
+ // Raw pointers don't inherit mutability.
583
+ ty:: RawPtr ( _) => return hir:: Mutability :: Not ,
584
+ // assignment to deref of an `&mut`
585
+ // borrowed pointer implies that the
586
+ // pointer itself must be unique, but not
587
+ // necessarily *mutable*
588
+ ty:: Ref ( .., hir:: Mutability :: Mut ) => is_mutbl = hir:: Mutability :: Mut ,
589
+ ty:: Ref ( .., hir:: Mutability :: Not ) => return hir:: Mutability :: Not ,
590
+ _ => ( ) ,
591
+ }
592
+ }
593
+
594
+ is_mutbl
595
+ }
545
596
}
546
597
547
598
struct InferBorrowKind < ' a , ' tcx > {
0 commit comments