Skip to content

Commit 560ef6d

Browse files
author
Albin Stjerna
committed
Polonius: emit variable access facts
1 parent 9cd1a11 commit 560ef6d

File tree

3 files changed

+50
-11
lines changed

3 files changed

+50
-11
lines changed

src/librustc_mir/borrow_check/nll/facts.rs

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ impl AllFactsExt for AllFacts {
6868
path_belongs_to_var,
6969
initialized_at,
7070
moved_out_at,
71+
path_accessed_at,
7172
])
7273
}
7374
Ok(())

src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub(super) fn generate<'tcx>(
6060
if !live_locals.is_empty() {
6161
trace::trace(typeck, body, elements, flow_inits, move_data, live_locals);
6262

63-
polonius::populate_var_liveness_facts(typeck, body, location_table);
63+
polonius::populate_access_facts(typeck, body, location_table, move_data);
6464
}
6565
}
6666

src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs

+48-10
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,28 @@
11
use crate::borrow_check::location::{LocationIndex, LocationTable};
2+
use crate::dataflow::indexes::MovePathIndex;
3+
use crate::dataflow::move_paths::{LookupResult, MoveData};
24
use crate::util::liveness::{categorize, DefUse};
3-
use rustc::mir::visit::{PlaceContext, Visitor};
4-
use rustc::mir::{Body, Local, Location};
5+
use rustc::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
6+
use rustc::mir::{Body, Local, Location, Place};
57
use rustc::ty::subst::Kind;
68
use rustc::ty::Ty;
79

810
use super::TypeChecker;
911

1012
type VarPointRelations = Vec<(Local, LocationIndex)>;
13+
type MovePathPointRelations = Vec<(MovePathIndex, LocationIndex)>;
1114

12-
struct LivenessPointFactsExtractor<'me> {
15+
struct UseFactsExtractor<'me> {
1316
var_defined: &'me mut VarPointRelations,
1417
var_used: &'me mut VarPointRelations,
1518
location_table: &'me LocationTable,
1619
var_drop_used: &'me mut VarPointRelations,
20+
move_data: &'me MoveData<'me>,
21+
path_accessed_at: &'me mut MovePathPointRelations,
1722
}
1823

1924
// A Visitor to walk through the MIR and extract point-wise facts
20-
impl LivenessPointFactsExtractor<'_> {
25+
impl UseFactsExtractor<'_> {
2126
fn location_to_index(&self, location: Location) -> LocationIndex {
2227
self.location_table.mid_index(location)
2328
}
@@ -36,9 +41,21 @@ impl LivenessPointFactsExtractor<'_> {
3641
debug!("LivenessFactsExtractor::insert_drop_use()");
3742
self.var_drop_used.push((local, self.location_to_index(location)));
3843
}
44+
45+
fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
46+
debug!("LivenessFactsExtractor::insert_path_access({:?}, {:?})", path, location);
47+
self.path_accessed_at.push((path, self.location_to_index(location)));
48+
}
49+
50+
fn place_to_mpi(&self, place: &Place<'_>) -> Option<MovePathIndex> {
51+
match self.move_data.rev_lookup.find(place.as_ref()) {
52+
LookupResult::Exact(mpi) => Some(mpi),
53+
LookupResult::Parent(mmpi) => mmpi,
54+
}
55+
}
3956
}
4057

41-
impl Visitor<'tcx> for LivenessPointFactsExtractor<'_> {
58+
impl Visitor<'tcx> for UseFactsExtractor<'_> {
4259
fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
4360
match categorize(context) {
4461
Some(DefUse::Def) => self.insert_def(local, location),
@@ -47,6 +64,24 @@ impl Visitor<'tcx> for LivenessPointFactsExtractor<'_> {
4764
_ => (),
4865
}
4966
}
67+
68+
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
69+
self.super_place(place, context, location);
70+
match context {
71+
PlaceContext::NonMutatingUse(_) => {
72+
if let Some(mpi) = self.place_to_mpi(place) {
73+
self.insert_path_access(mpi, location);
74+
}
75+
}
76+
77+
PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
78+
if let Some(mpi) = self.place_to_mpi(place) {
79+
self.insert_path_access(mpi, location);
80+
}
81+
}
82+
_ => (),
83+
}
84+
}
5085
}
5186

5287
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
6095
});
6196
}
6297

63-
pub(super) fn populate_var_liveness_facts(
98+
pub(super) fn populate_access_facts(
6499
typeck: &mut TypeChecker<'_, 'tcx>,
65-
mir: &Body<'tcx>,
100+
body: &Body<'tcx>,
66101
location_table: &LocationTable,
102+
move_data: &MoveData<'_>,
67103
) {
68104
debug!("populate_var_liveness_facts()");
69105

70106
if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
71-
LivenessPointFactsExtractor {
107+
UseFactsExtractor {
72108
var_defined: &mut facts.var_defined,
73109
var_used: &mut facts.var_used,
74110
var_drop_used: &mut facts.var_drop_used,
111+
path_accessed_at: &mut facts.path_accessed_at,
75112
location_table,
113+
move_data,
76114
}
77-
.visit_body(mir);
115+
.visit_body(body);
78116
}
79117

80-
for (local, local_decl) in mir.local_decls.iter_enumerated() {
118+
for (local, local_decl) in body.local_decls.iter_enumerated() {
81119
add_var_uses_regions(typeck, local, local_decl.ty);
82120
}
83121
}

0 commit comments

Comments
 (0)