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)
}
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),
_ => (),
}
}
+
+ 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>) {
});
}
-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);
}
}