Polonius: emit variable access facts
This commit is contained in:
parent
9cd1a11571
commit
560ef6d710
3 changed files with 50 additions and 11 deletions
|
|
@ -68,6 +68,7 @@ impl AllFactsExt for AllFacts {
|
|||
path_belongs_to_var,
|
||||
initialized_at,
|
||||
moved_out_at,
|
||||
path_accessed_at,
|
||||
])
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 @@ impl LivenessPointFactsExtractor<'_> {
|
|||
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 @@ impl Visitor<'tcx> for LivenessPointFactsExtractor<'_> {
|
|||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue