Skip to content

Commit 2fd4438

Browse files
committed
clean up emit_access_facts
- remove dependency on `TypeChecker` - move to legacy fact generation module
1 parent 0894fb0 commit 2fd4438

File tree

4 files changed

+120
-104
lines changed

4 files changed

+120
-104
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
2+
use rustc_middle::mir::{Body, Local, Location, Place};
3+
use rustc_middle::ty::TyCtxt;
4+
use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
5+
use tracing::debug;
6+
7+
use crate::def_use::{self, DefUse};
8+
use crate::facts::AllFacts;
9+
use crate::location::{LocationIndex, LocationTable};
10+
use crate::universal_regions::UniversalRegions;
11+
12+
type VarPointRelation = Vec<(Local, LocationIndex)>;
13+
type PathPointRelation = Vec<(MovePathIndex, LocationIndex)>;
14+
15+
/// Emit polonius facts for variable defs, uses, drops, and path accesses.
16+
pub(crate) fn emit_access_facts<'tcx>(
17+
tcx: TyCtxt<'tcx>,
18+
body: &Body<'tcx>,
19+
move_data: &MoveData<'tcx>,
20+
universal_regions: &UniversalRegions<'tcx>,
21+
location_table: &LocationTable,
22+
all_facts: &mut Option<AllFacts>,
23+
) {
24+
if let Some(facts) = all_facts.as_mut() {
25+
debug!("emit_access_facts()");
26+
27+
let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation");
28+
let mut extractor = AccessFactsExtractor {
29+
var_defined_at: &mut facts.var_defined_at,
30+
var_used_at: &mut facts.var_used_at,
31+
var_dropped_at: &mut facts.var_dropped_at,
32+
path_accessed_at_base: &mut facts.path_accessed_at_base,
33+
location_table,
34+
move_data,
35+
};
36+
extractor.visit_body(body);
37+
38+
for (local, local_decl) in body.local_decls.iter_enumerated() {
39+
debug!(
40+
"add use_of_var_derefs_origin facts - local={:?}, type={:?}",
41+
local, local_decl.ty
42+
);
43+
tcx.for_each_free_region(&local_decl.ty, |region| {
44+
let region_vid = universal_regions.to_region_vid(region);
45+
facts.use_of_var_derefs_origin.push((local, region_vid.into()));
46+
});
47+
}
48+
}
49+
}
50+
51+
/// MIR visitor extracting point-wise facts about accesses.
52+
struct AccessFactsExtractor<'a, 'tcx> {
53+
var_defined_at: &'a mut VarPointRelation,
54+
var_used_at: &'a mut VarPointRelation,
55+
location_table: &'a LocationTable,
56+
var_dropped_at: &'a mut VarPointRelation,
57+
move_data: &'a MoveData<'tcx>,
58+
path_accessed_at_base: &'a mut PathPointRelation,
59+
}
60+
61+
impl<'tcx> AccessFactsExtractor<'_, 'tcx> {
62+
fn location_to_index(&self, location: Location) -> LocationIndex {
63+
self.location_table.mid_index(location)
64+
}
65+
}
66+
67+
impl<'a, 'tcx> Visitor<'tcx> for AccessFactsExtractor<'a, 'tcx> {
68+
fn visit_local(&mut self, local: Local, context: PlaceContext, location: Location) {
69+
match def_use::categorize(context) {
70+
Some(DefUse::Def) => {
71+
debug!("AccessFactsExtractor - emit def");
72+
self.var_defined_at.push((local, self.location_to_index(location)));
73+
}
74+
Some(DefUse::Use) => {
75+
debug!("AccessFactsExtractor - emit use");
76+
self.var_used_at.push((local, self.location_to_index(location)));
77+
}
78+
Some(DefUse::Drop) => {
79+
debug!("AccessFactsExtractor - emit drop");
80+
self.var_dropped_at.push((local, self.location_to_index(location)));
81+
}
82+
_ => (),
83+
}
84+
}
85+
86+
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
87+
self.super_place(place, context, location);
88+
89+
match context {
90+
PlaceContext::NonMutatingUse(_)
91+
| PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
92+
let path = match self.move_data.rev_lookup.find(place.as_ref()) {
93+
LookupResult::Exact(path) | LookupResult::Parent(Some(path)) => path,
94+
_ => {
95+
// There's no path access to emit.
96+
return;
97+
}
98+
};
99+
debug!("AccessFactsExtractor - emit path access ({path:?}, {location:?})");
100+
self.path_accessed_at_base.push((path, self.location_to_index(location)));
101+
}
102+
103+
_ => {}
104+
}
105+
}
106+
}

compiler/rustc_borrowck/src/polonius/legacy/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,12 @@ use crate::facts::{AllFacts, PoloniusRegionVid};
1313
use crate::location::LocationTable;
1414
use crate::type_check::free_region_relations::UniversalRegionRelations;
1515

16+
mod accesses;
1617
mod loan_invalidations;
1718
mod loan_kills;
1819

20+
pub(crate) use accesses::emit_access_facts;
21+
1922
/// When requested, emit most of the facts needed by polonius:
2023
/// - moves and assignments
2124
/// - universal regions and their relations

compiler/rustc_borrowck/src/type_check/liveness/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,14 @@ pub(super) fn generate<'a, 'tcx>(
4545
let (relevant_live_locals, boring_locals) =
4646
compute_relevant_live_locals(typeck.tcx(), &free_regions, body);
4747

48-
polonius::emit_access_facts(typeck, body, move_data);
48+
crate::polonius::legacy::emit_access_facts(
49+
typeck.tcx(),
50+
body,
51+
move_data,
52+
typeck.universal_regions,
53+
typeck.location_table,
54+
typeck.all_facts,
55+
);
4956

5057
trace::trace(
5158
typeck,
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,11 @@
1-
use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
2-
use rustc_middle::mir::{Body, Local, Location, Place};
1+
use rustc_middle::mir::Local;
32
use rustc_middle::ty::GenericArg;
4-
use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
53
use tracing::debug;
64

7-
use super::TypeChecker;
8-
use crate::def_use::{self, DefUse};
9-
use crate::location::{LocationIndex, LocationTable};
10-
11-
type VarPointRelation = Vec<(Local, LocationIndex)>;
12-
type PathPointRelation = Vec<(MovePathIndex, LocationIndex)>;
13-
14-
/// Emit polonius facts for variable defs, uses, drops, and path accesses.
15-
pub(super) fn emit_access_facts<'a, 'tcx>(
16-
typeck: &mut TypeChecker<'a, 'tcx>,
17-
body: &Body<'tcx>,
18-
move_data: &MoveData<'tcx>,
19-
) {
20-
if let Some(facts) = typeck.all_facts.as_mut() {
21-
debug!("emit_access_facts()");
22-
23-
let _prof_timer = typeck.infcx.tcx.prof.generic_activity("polonius_fact_generation");
24-
let location_table = typeck.location_table;
25-
26-
let mut extractor = AccessFactsExtractor {
27-
var_defined_at: &mut facts.var_defined_at,
28-
var_used_at: &mut facts.var_used_at,
29-
var_dropped_at: &mut facts.var_dropped_at,
30-
path_accessed_at_base: &mut facts.path_accessed_at_base,
31-
location_table,
32-
move_data,
33-
};
34-
extractor.visit_body(body);
35-
36-
for (local, local_decl) in body.local_decls.iter_enumerated() {
37-
debug!(
38-
"add use_of_var_derefs_origin facts - local={:?}, type={:?}",
39-
local, local_decl.ty
40-
);
41-
let universal_regions = &typeck.universal_regions;
42-
typeck.infcx.tcx.for_each_free_region(&local_decl.ty, |region| {
43-
let region_vid = universal_regions.to_region_vid(region);
44-
facts.use_of_var_derefs_origin.push((local, region_vid.into()));
45-
});
46-
}
47-
}
48-
}
5+
use crate::type_check::TypeChecker;
496

507
/// For every potentially drop()-touched region `region` in `local`'s type
51-
/// (`kind`), emit a Polonius `use_of_var_derefs_origin(local, origin)` fact.
8+
/// (`kind`), emit a Polonius `drop_of_var_derefs_origin(local, origin)` fact.
529
pub(super) fn emit_drop_facts<'tcx>(
5310
typeck: &mut TypeChecker<'_, 'tcx>,
5411
local: Local,
@@ -64,60 +21,3 @@ pub(super) fn emit_drop_facts<'tcx>(
6421
});
6522
}
6623
}
67-
68-
/// MIR visitor extracting point-wise facts about accesses.
69-
struct AccessFactsExtractor<'a, 'tcx> {
70-
var_defined_at: &'a mut VarPointRelation,
71-
var_used_at: &'a mut VarPointRelation,
72-
location_table: &'a LocationTable,
73-
var_dropped_at: &'a mut VarPointRelation,
74-
move_data: &'a MoveData<'tcx>,
75-
path_accessed_at_base: &'a mut PathPointRelation,
76-
}
77-
78-
impl<'tcx> AccessFactsExtractor<'_, 'tcx> {
79-
fn location_to_index(&self, location: Location) -> LocationIndex {
80-
self.location_table.mid_index(location)
81-
}
82-
}
83-
84-
impl<'a, 'tcx> Visitor<'tcx> for AccessFactsExtractor<'a, 'tcx> {
85-
fn visit_local(&mut self, local: Local, context: PlaceContext, location: Location) {
86-
match def_use::categorize(context) {
87-
Some(DefUse::Def) => {
88-
debug!("AccessFactsExtractor - emit def");
89-
self.var_defined_at.push((local, self.location_to_index(location)));
90-
}
91-
Some(DefUse::Use) => {
92-
debug!("AccessFactsExtractor - emit use");
93-
self.var_used_at.push((local, self.location_to_index(location)));
94-
}
95-
Some(DefUse::Drop) => {
96-
debug!("AccessFactsExtractor - emit drop");
97-
self.var_dropped_at.push((local, self.location_to_index(location)));
98-
}
99-
_ => (),
100-
}
101-
}
102-
103-
fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
104-
self.super_place(place, context, location);
105-
106-
match context {
107-
PlaceContext::NonMutatingUse(_)
108-
| PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
109-
let path = match self.move_data.rev_lookup.find(place.as_ref()) {
110-
LookupResult::Exact(path) | LookupResult::Parent(Some(path)) => path,
111-
_ => {
112-
// There's no path access to emit.
113-
return;
114-
}
115-
};
116-
debug!("AccessFactsExtractor - emit path access ({path:?}, {location:?})");
117-
self.path_accessed_at_base.push((path, self.location_to_index(location)));
118-
}
119-
120-
_ => {}
121-
}
122-
}
123-
}

0 commit comments

Comments
 (0)