@@ -140,7 +140,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
140
140
node_id : id,
141
141
move_data : & mdpe. move_data ,
142
142
param_env : param_env,
143
- storage_drop_or_dead_error_reported : FxHashSet ( ) ,
143
+ storage_dead_or_drop_error_reported : FxHashSet ( ) ,
144
144
} ;
145
145
146
146
let mut state = InProgress :: new ( flow_borrows,
@@ -159,10 +159,10 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
159
159
node_id : ast:: NodeId ,
160
160
move_data : & ' cx MoveData < ' tcx > ,
161
161
param_env : ParamEnv < ' gcx > ,
162
- /// This field keeps track of when storage drop or dead errors are reported
162
+ /// This field keeps track of when storage dead or drop errors are reported
163
163
/// in order to stop duplicate error reporting and identify the conditions required
164
164
/// for a "temporary value dropped here while still borrowed" error. See #45360.
165
- storage_drop_or_dead_error_reported : FxHashSet < Local > ,
165
+ storage_dead_or_drop_error_reported : FxHashSet < Local > ,
166
166
}
167
167
168
168
// (forced to be `pub` due to its use as an associated type below.)
@@ -296,15 +296,9 @@ impl<'cx, 'gcx, 'tcx> DataflowResultsConsumer<'cx, 'tcx> for MirBorrowckCtxt<'cx
296
296
}
297
297
298
298
StatementKind :: StorageDead ( local) => {
299
- if !self . storage_drop_or_dead_error_reported . contains ( & local) {
300
- let error_reported = self . access_lvalue ( ContextKind :: StorageDead . new ( location) ,
301
- ( & Lvalue :: Local ( local) , span) ,
302
- ( Shallow ( None ) , Write ( WriteKind :: StorageDeadOrDrop ) ) , flow_state) ;
303
-
304
- if error_reported {
305
- self . storage_drop_or_dead_error_reported . insert ( local) ;
306
- }
307
- }
299
+ self . access_lvalue ( ContextKind :: StorageDead . new ( location) ,
300
+ ( & Lvalue :: Local ( local) , span) ,
301
+ ( Shallow ( None ) , Write ( WriteKind :: StorageDeadOrDrop ) ) , flow_state) ;
308
302
}
309
303
}
310
304
}
@@ -523,9 +517,21 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
523
517
context : Context ,
524
518
lvalue_span : ( & Lvalue < ' tcx > , Span ) ,
525
519
kind : ( ShallowOrDeep , ReadOrWrite ) ,
526
- flow_state : & InProgress < ' cx , ' gcx , ' tcx > ) -> bool {
520
+ flow_state : & InProgress < ' cx , ' gcx , ' tcx > ) {
527
521
let ( sd, rw) = kind;
528
522
523
+ let storage_dead_or_drop_local = match ( lvalue_span. 0 , rw) {
524
+ ( & Lvalue :: Local ( local) , Write ( WriteKind :: StorageDeadOrDrop ) ) => Some ( local) ,
525
+ _ => None
526
+ } ;
527
+
528
+ // Check if error has already been reported to stop duplicate reporting.
529
+ if let Some ( local) = storage_dead_or_drop_local {
530
+ if self . storage_dead_or_drop_error_reported . contains ( & local) {
531
+ return ;
532
+ }
533
+ }
534
+
529
535
// Check permissions
530
536
self . check_access_permissions ( lvalue_span, rw) ;
531
537
@@ -590,7 +596,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
590
596
}
591
597
}
592
598
} ) ;
593
- error_reported
599
+
600
+ if error_reported {
601
+ if let Some ( local) = storage_dead_or_drop_local {
602
+ self . storage_dead_or_drop_error_reported . insert ( local) ;
603
+ }
604
+ }
594
605
}
595
606
596
607
fn mutate_lvalue ( & mut self ,
@@ -708,39 +719,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
708
719
let erased_ty = gcx. lift ( & self . tcx . erase_regions ( & ty) ) . unwrap ( ) ;
709
720
let moves_by_default = erased_ty. moves_by_default ( gcx, self . param_env , DUMMY_SP ) ;
710
721
711
- // Check if error has already been reported to stop duplicate reporting.
712
- let has_storage_drop_or_dead_error_reported = match * lvalue {
713
- Lvalue :: Local ( local) => self . storage_drop_or_dead_error_reported . contains ( & local) ,
714
- _ => false ,
715
- } ;
716
-
717
- // If the error has been reported already, then we don't need the access_lvalue call.
718
- if !has_storage_drop_or_dead_error_reported || consume_via_drop != ConsumeKind :: Drop {
719
- let error_reported;
720
-
721
- if moves_by_default {
722
- let kind = match consume_via_drop {
723
- ConsumeKind :: Drop => WriteKind :: StorageDeadOrDrop ,
724
- _ => WriteKind :: Move ,
725
- } ;
726
-
727
- // move of lvalue: check if this is move of already borrowed path
728
- error_reported = self . access_lvalue ( context, lvalue_span,
729
- ( Deep , Write ( kind) ) , flow_state) ;
730
- } else {
731
- // copy of lvalue: check if this is "copy of frozen path"
732
- // (FIXME: see check_loans.rs)
733
- error_reported = self . access_lvalue ( context, lvalue_span,
734
- ( Deep , Read ( ReadKind :: Copy ) ) , flow_state) ;
735
- }
722
+ if moves_by_default {
723
+ let kind = match consume_via_drop {
724
+ ConsumeKind :: Drop => WriteKind :: StorageDeadOrDrop ,
725
+ _ => WriteKind :: Move ,
726
+ } ;
736
727
737
- // If there was an error, then we keep track of it so as to deduplicate it.
738
- // We only do this on ConsumeKind::Drop.
739
- if error_reported && consume_via_drop == ConsumeKind :: Drop {
740
- if let Lvalue :: Local ( local) = * lvalue {
741
- self . storage_drop_or_dead_error_reported . insert ( local) ;
742
- }
743
- }
728
+ // move of lvalue: check if this is move of already borrowed path
729
+ self . access_lvalue ( context, lvalue_span, ( Deep , Write ( kind) ) , flow_state) ;
730
+ } else {
731
+ // copy of lvalue: check if this is "copy of frozen path"
732
+ // (FIXME: see check_loans.rs)
733
+ self . access_lvalue ( context, lvalue_span, ( Deep , Read ( ReadKind :: Copy ) ) , flow_state) ;
744
734
}
745
735
746
736
// Finally, check if path was already moved.
0 commit comments