]> git.lizzy.rs Git - rust.git/commitdiff
Polonius: emit variable access facts
authorAlbin Stjerna <albin.stjerna@gmail.com>
Wed, 7 Aug 2019 15:44:35 +0000 (17:44 +0200)
committerAlbin Stjerna <albin.stjerna@gmail.com>
Wed, 4 Sep 2019 07:46:44 +0000 (09:46 +0200)
src/librustc_mir/borrow_check/nll/facts.rs
src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs

index b11e5e7a85d0ebb9f3c2e65b1093f22705e8a7bc..f0beb4d3ae32d773e4afc09aa9a6a07b02f5c589 100644 (file)
@@ -68,6 +68,7 @@ macro_rules! write_facts_to_path {
                 path_belongs_to_var,
                 initialized_at,
                 moved_out_at,
+                path_accessed_at,
             ])
         }
         Ok(())
index 25d7985653c0ea2454f3a39ccd8ebc8d246ec467..3f2ec1ba970173910e7ac85ffbc574afad7952fc 100644 (file)
@@ -60,7 +60,7 @@ pub(super) fn generate<'tcx>(
     if !live_locals.is_empty() {
         trace::trace(typeck, body, elements, flow_inits, move_data, live_locals);
 
-        polonius::populate_var_liveness_facts(typeck, body, location_table);
+        polonius::populate_access_facts(typeck, body, location_table, move_data);
     }
 }
 
index dcdacbbe5be06b5a7b07d86ac737ffe1191b375b..d61464b3f387d52d84f904a0592994d419f03326 100644 (file)
@@ -1,23 +1,28 @@
 use crate::borrow_check::location::{LocationIndex, LocationTable};
+use crate::dataflow::indexes::MovePathIndex;
+use crate::dataflow::move_paths::{LookupResult, MoveData};
 use crate::util::liveness::{categorize, DefUse};
-use rustc::mir::visit::{PlaceContext, Visitor};
-use rustc::mir::{Body, Local, Location};
+use rustc::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
+use rustc::mir::{Body, Local, Location, Place};
 use rustc::ty::subst::Kind;
 use rustc::ty::Ty;
 
 use super::TypeChecker;
 
 type VarPointRelations = Vec<(Local, LocationIndex)>;
+type MovePathPointRelations = Vec<(MovePathIndex, LocationIndex)>;
 
-struct LivenessPointFactsExtractor<'me> {
+struct UseFactsExtractor<'me> {
     var_defined: &'me mut VarPointRelations,
     var_used: &'me mut VarPointRelations,
     location_table: &'me LocationTable,
     var_drop_used: &'me mut VarPointRelations,
+    move_data: &'me MoveData<'me>,
+    path_accessed_at: &'me mut MovePathPointRelations,
 }
 
 // A Visitor to walk through the MIR and extract point-wise facts
-impl LivenessPointFactsExtractor<'_> {
+impl UseFactsExtractor<'_> {
     fn location_to_index(&self, location: Location) -> LocationIndex {
         self.location_table.mid_index(location)
     }
@@ -36,9 +41,21 @@ fn insert_drop_use(&mut self, local: Local, location: Location) {
         debug!("LivenessFactsExtractor::insert_drop_use()");
         self.var_drop_used.push((local, self.location_to_index(location)));
     }
+
+    fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
+        debug!("LivenessFactsExtractor::insert_path_access({:?}, {:?})", path, location);
+        self.path_accessed_at.push((path, self.location_to_index(location)));
+    }
+
+    fn place_to_mpi(&self, place: &Place<'_>) -> Option<MovePathIndex> {
+        match self.move_data.rev_lookup.find(place.as_ref()) {
+            LookupResult::Exact(mpi) => Some(mpi),
+            LookupResult::Parent(mmpi) => mmpi,
+        }
+    }
 }
 
-impl Visitor<'tcx> for LivenessPointFactsExtractor<'_> {
+impl Visitor<'tcx> for UseFactsExtractor<'_> {
     fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
         match categorize(context) {
             Some(DefUse::Def) => self.insert_def(local, location),
@@ -47,6 +64,24 @@ fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Locat
             _ => (),
         }
     }
+
+    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
+        self.super_place(place, context, location);
+        match context {
+            PlaceContext::NonMutatingUse(_) => {
+                if let Some(mpi) = self.place_to_mpi(place) {
+                    self.insert_path_access(mpi, location);
+                }
+            }
+
+            PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
+                if let Some(mpi) = self.place_to_mpi(place) {
+                    self.insert_path_access(mpi, location);
+                }
+            }
+            _ => (),
+        }
+    }
 }
 
 fn add_var_uses_regions(typeck: &mut TypeChecker<'_, 'tcx>, local: Local, ty: Ty<'tcx>) {
@@ -60,24 +95,27 @@ fn add_var_uses_regions(typeck: &mut TypeChecker<'_, 'tcx>, local: Local, ty: Ty
     });
 }
 
-pub(super) fn populate_var_liveness_facts(
+pub(super) fn populate_access_facts(
     typeck: &mut TypeChecker<'_, 'tcx>,
-    mir: &Body<'tcx>,
+    body: &Body<'tcx>,
     location_table: &LocationTable,
+    move_data: &MoveData<'_>,
 ) {
     debug!("populate_var_liveness_facts()");
 
     if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
-        LivenessPointFactsExtractor {
+        UseFactsExtractor {
             var_defined: &mut facts.var_defined,
             var_used: &mut facts.var_used,
             var_drop_used: &mut facts.var_drop_used,
+            path_accessed_at: &mut facts.path_accessed_at,
             location_table,
+            move_data,
         }
-        .visit_body(mir);
+        .visit_body(body);
     }
 
-    for (local, local_decl) in mir.local_decls.iter_enumerated() {
+    for (local, local_decl) in body.local_decls.iter_enumerated() {
         add_var_uses_regions(typeck, local, local_decl.ty);
     }
 }