about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2017-11-21 01:50:04 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2017-11-28 04:11:09 +0200
commit0477319afb369d0e2bdb29b813ef10660a6594f5 (patch)
treeff557e3f3b617c08dba8c2a081488de89ee09124
parentb087a991fca51c365ce46ad470d85b99f7c9005a (diff)
downloadrust-0477319afb369d0e2bdb29b813ef10660a6594f5.tar.gz
rust-0477319afb369d0e2bdb29b813ef10660a6594f5.zip
rustc_mir: move storage_dead_or_drop_error_reported logic to access_lvalue.
-rw-r--r--src/librustc_mir/borrow_check.rs82
1 files changed, 36 insertions, 46 deletions
diff --git a/src/librustc_mir/borrow_check.rs b/src/librustc_mir/borrow_check.rs
index 9a05bbea487..ef41621c411 100644
--- a/src/librustc_mir/borrow_check.rs
+++ b/src/librustc_mir/borrow_check.rs
@@ -140,7 +140,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
         node_id: id,
         move_data: &mdpe.move_data,
         param_env: param_env,
-        storage_drop_or_dead_error_reported: FxHashSet(),
+        storage_dead_or_drop_error_reported: FxHashSet(),
     };
 
     let mut state = InProgress::new(flow_borrows,
@@ -159,10 +159,10 @@ pub struct MirBorrowckCtxt<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
     node_id: ast::NodeId,
     move_data: &'cx MoveData<'tcx>,
     param_env: ParamEnv<'gcx>,
-    /// This field keeps track of when storage drop or dead errors are reported
+    /// This field keeps track of when storage dead or drop errors are reported
     /// in order to stop duplicate error reporting and identify the conditions required
     /// for a "temporary value dropped here while still borrowed" error. See #45360.
-    storage_drop_or_dead_error_reported: FxHashSet<Local>,
+    storage_dead_or_drop_error_reported: FxHashSet<Local>,
 }
 
 // (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
             }
 
             StatementKind::StorageDead(local) => {
-                if !self.storage_drop_or_dead_error_reported.contains(&local) {
-                    let error_reported = self.access_lvalue(ContextKind::StorageDead.new(location),
-                        (&Lvalue::Local(local), span),
-                        (Shallow(None), Write(WriteKind::StorageDeadOrDrop)), flow_state);
-
-                    if error_reported {
-                        self.storage_drop_or_dead_error_reported.insert(local);
-                    }
-                }
+                self.access_lvalue(ContextKind::StorageDead.new(location),
+                    (&Lvalue::Local(local), span),
+                    (Shallow(None), Write(WriteKind::StorageDeadOrDrop)), flow_state);
             }
         }
     }
@@ -523,9 +517,21 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                      context: Context,
                      lvalue_span: (&Lvalue<'tcx>, Span),
                      kind: (ShallowOrDeep, ReadOrWrite),
-                     flow_state: &InProgress<'cx, 'gcx, 'tcx>) -> bool {
+                     flow_state: &InProgress<'cx, 'gcx, 'tcx>) {
         let (sd, rw) = kind;
 
+        let storage_dead_or_drop_local = match (lvalue_span.0, rw) {
+            (&Lvalue::Local(local), Write(WriteKind::StorageDeadOrDrop)) => Some(local),
+            _ => None
+        };
+
+        // Check if error has already been reported to stop duplicate reporting.
+        if let Some(local) = storage_dead_or_drop_local {
+            if self.storage_dead_or_drop_error_reported.contains(&local) {
+                return;
+            }
+        }
+
         // Check permissions
         self.check_access_permissions(lvalue_span, rw);
 
@@ -590,7 +596,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     }
                 }
             });
-        error_reported
+
+        if error_reported {
+            if let Some(local) = storage_dead_or_drop_local {
+                self.storage_dead_or_drop_error_reported.insert(local);
+            }
+        }
     }
 
     fn mutate_lvalue(&mut self,
@@ -708,39 +719,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
         let erased_ty = gcx.lift(&self.tcx.erase_regions(&ty)).unwrap();
         let moves_by_default = erased_ty.moves_by_default(gcx, self.param_env, DUMMY_SP);
 
-        // Check if error has already been reported to stop duplicate reporting.
-        let has_storage_drop_or_dead_error_reported = match *lvalue {
-            Lvalue::Local(local) => self.storage_drop_or_dead_error_reported.contains(&local),
-            _ => false,
-        };
-
-        // If the error has been reported already, then we don't need the access_lvalue call.
-        if !has_storage_drop_or_dead_error_reported || consume_via_drop != ConsumeKind::Drop {
-            let error_reported;
-
-            if moves_by_default {
-                let kind = match consume_via_drop {
-                    ConsumeKind::Drop => WriteKind::StorageDeadOrDrop,
-                    _ => WriteKind::Move,
-                };
-
-                // move of lvalue: check if this is move of already borrowed path
-                error_reported = self.access_lvalue(context, lvalue_span,
-                                                    (Deep, Write(kind)), flow_state);
-            } else {
-                // copy of lvalue: check if this is "copy of frozen path"
-                // (FIXME: see check_loans.rs)
-                error_reported = self.access_lvalue(context, lvalue_span,
-                                                    (Deep, Read(ReadKind::Copy)), flow_state);
-            }
+        if moves_by_default {
+            let kind = match consume_via_drop {
+                ConsumeKind::Drop => WriteKind::StorageDeadOrDrop,
+                _ => WriteKind::Move,
+            };
 
-            // If there was an error, then we keep track of it so as to deduplicate it.
-            // We only do this on ConsumeKind::Drop.
-            if error_reported && consume_via_drop == ConsumeKind::Drop {
-                if let Lvalue::Local(local) = *lvalue {
-                    self.storage_drop_or_dead_error_reported.insert(local);
-                }
-            }
+            // move of lvalue: check if this is move of already borrowed path
+            self.access_lvalue(context, lvalue_span, (Deep, Write(kind)), flow_state);
+        } else {
+            // copy of lvalue: check if this is "copy of frozen path"
+            // (FIXME: see check_loans.rs)
+            self.access_lvalue(context, lvalue_span, (Deep, Read(ReadKind::Copy)), flow_state);
         }
 
         // Finally, check if path was already moved.