Skip to content

Commit bfd88b0

Browse files
committed
simplify polonius constraint generation
1 parent f53412a commit bfd88b0

File tree

3 files changed

+83
-107
lines changed

3 files changed

+83
-107
lines changed

compiler/rustc_borrowck/src/nll.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
158158
borrow_set,
159159
);
160160
polonius::emit_cfg_and_loan_kills_facts(
161-
infcx,
161+
infcx.tcx,
162162
&mut all_facts,
163163
location_table,
164164
body,
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,52 @@
11
#![deny(rustc::untranslatable_diagnostic)]
22
#![deny(rustc::diagnostic_outside_of_impl)]
3-
use rustc_infer::infer::InferCtxt;
43
use rustc_middle::mir::visit::Visitor;
54
use rustc_middle::mir::{
65
Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind,
76
Terminator, TerminatorKind, UserTypeProjection,
87
};
9-
use rustc_middle::ty::{self};
8+
use rustc_middle::ty::{TyCtxt, Variance};
109

1110
use crate::{borrow_set::BorrowSet, facts::AllFacts, location::LocationTable, places_conflict};
1211

1312
pub(super) fn generate_constraints<'tcx>(
14-
infcx: &InferCtxt<'tcx>,
15-
all_facts: &mut Option<AllFacts>,
13+
tcx: TyCtxt<'tcx>,
14+
all_facts: &mut AllFacts,
1615
location_table: &LocationTable,
1716
body: &Body<'tcx>,
1817
borrow_set: &BorrowSet<'tcx>,
1918
) {
20-
let mut cg = ConstraintGeneration { borrow_set, infcx, location_table, all_facts, body };
19+
let _prof_timer = tcx.prof.generic_activity("polonius_fact_generation");
20+
let mut cg = ConstraintGeneration { borrow_set, tcx, location_table, all_facts, body };
2121
for (bb, data) in body.basic_blocks.iter_enumerated() {
2222
cg.visit_basic_block_data(bb, data);
2323
}
2424
}
2525

2626
/// 'cg = the duration of the constraint generation process itself.
2727
struct ConstraintGeneration<'cg, 'tcx> {
28-
infcx: &'cg InferCtxt<'tcx>,
29-
all_facts: &'cg mut Option<AllFacts>,
28+
tcx: TyCtxt<'tcx>,
29+
all_facts: &'cg mut AllFacts,
3030
location_table: &'cg LocationTable,
3131
borrow_set: &'cg BorrowSet<'tcx>,
3232
body: &'cg Body<'tcx>,
3333
}
3434

3535
impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> {
3636
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
37-
if let Some(all_facts) = self.all_facts {
38-
let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
39-
all_facts.cfg_edge.push((
40-
self.location_table.start_index(location),
41-
self.location_table.mid_index(location),
42-
));
43-
44-
all_facts.cfg_edge.push((
45-
self.location_table.mid_index(location),
46-
self.location_table.start_index(location.successor_within_block()),
47-
));
48-
49-
// If there are borrows on this now dead local, we need to record them as `killed`.
50-
if let StatementKind::StorageDead(local) = statement.kind {
51-
record_killed_borrows_for_local(
52-
all_facts,
53-
self.borrow_set,
54-
self.location_table,
55-
local,
56-
location,
57-
);
58-
}
37+
self.all_facts.cfg_edge.push((
38+
self.location_table.start_index(location),
39+
self.location_table.mid_index(location),
40+
));
41+
42+
self.all_facts.cfg_edge.push((
43+
self.location_table.mid_index(location),
44+
self.location_table.start_index(location.successor_within_block()),
45+
));
46+
47+
// If there are borrows on this now dead local, we need to record them as `killed`.
48+
if let StatementKind::StorageDead(local) = statement.kind {
49+
self.record_killed_borrows_for_local(local, location);
5950
}
6051

6152
self.super_statement(statement, location);
@@ -70,21 +61,18 @@ impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> {
7061
}
7162

7263
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
73-
if let Some(all_facts) = self.all_facts {
74-
let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
75-
all_facts.cfg_edge.push((
76-
self.location_table.start_index(location),
64+
self.all_facts.cfg_edge.push((
65+
self.location_table.start_index(location),
66+
self.location_table.mid_index(location),
67+
));
68+
69+
let successor_blocks = terminator.successors();
70+
self.all_facts.cfg_edge.reserve(successor_blocks.size_hint().0);
71+
for successor_block in successor_blocks {
72+
self.all_facts.cfg_edge.push((
7773
self.location_table.mid_index(location),
74+
self.location_table.start_index(successor_block.start_location()),
7875
));
79-
80-
let successor_blocks = terminator.successors();
81-
all_facts.cfg_edge.reserve(successor_blocks.size_hint().0);
82-
for successor_block in successor_blocks {
83-
all_facts.cfg_edge.push((
84-
self.location_table.mid_index(location),
85-
self.location_table.start_index(successor_block.start_location()),
86-
));
87-
}
8876
}
8977

9078
// A `Call` terminator's return value can be a local which has borrows,
@@ -99,7 +87,7 @@ impl<'cg, 'tcx> Visitor<'tcx> for ConstraintGeneration<'cg, 'tcx> {
9987
fn visit_ascribe_user_ty(
10088
&mut self,
10189
_place: &Place<'tcx>,
102-
_variance: ty::Variance,
90+
_variance: Variance,
10391
_user_ty: &UserTypeProjection,
10492
_location: Location,
10593
) {
@@ -110,75 +98,59 @@ impl<'cx, 'tcx> ConstraintGeneration<'cx, 'tcx> {
11098
/// When recording facts for Polonius, records the borrows on the specified place
11199
/// as `killed`. For example, when assigning to a local, or on a call's return destination.
112100
fn record_killed_borrows_for_place(&mut self, place: Place<'tcx>, location: Location) {
113-
if let Some(all_facts) = self.all_facts {
114-
let _prof_timer = self.infcx.tcx.prof.generic_activity("polonius_fact_generation");
115-
116-
// Depending on the `Place` we're killing:
117-
// - if it's a local, or a single deref of a local,
118-
// we kill all the borrows on the local.
119-
// - if it's a deeper projection, we have to filter which
120-
// of the borrows are killed: the ones whose `borrowed_place`
121-
// conflicts with the `place`.
122-
match place.as_ref() {
123-
PlaceRef { local, projection: &[] }
124-
| PlaceRef { local, projection: &[ProjectionElem::Deref] } => {
125-
debug!(
126-
"Recording `killed` facts for borrows of local={:?} at location={:?}",
127-
local, location
128-
);
129-
130-
record_killed_borrows_for_local(
131-
all_facts,
132-
self.borrow_set,
133-
self.location_table,
134-
local,
135-
location,
136-
);
137-
}
101+
// Depending on the `Place` we're killing:
102+
// - if it's a local, or a single deref of a local,
103+
// we kill all the borrows on the local.
104+
// - if it's a deeper projection, we have to filter which
105+
// of the borrows are killed: the ones whose `borrowed_place`
106+
// conflicts with the `place`.
107+
match place.as_ref() {
108+
PlaceRef { local, projection: &[] }
109+
| PlaceRef { local, projection: &[ProjectionElem::Deref] } => {
110+
debug!(
111+
"Recording `killed` facts for borrows of local={:?} at location={:?}",
112+
local, location
113+
);
114+
115+
self.record_killed_borrows_for_local(local, location);
116+
}
138117

139-
PlaceRef { local, projection: &[.., _] } => {
140-
// Kill conflicting borrows of the innermost local.
141-
debug!(
142-
"Recording `killed` facts for borrows of \
118+
PlaceRef { local, projection: &[.., _] } => {
119+
// Kill conflicting borrows of the innermost local.
120+
debug!(
121+
"Recording `killed` facts for borrows of \
143122
innermost projected local={:?} at location={:?}",
144-
local, location
145-
);
146-
147-
if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) {
148-
for &borrow_index in borrow_indices {
149-
let places_conflict = places_conflict::places_conflict(
150-
self.infcx.tcx,
151-
self.body,
152-
self.borrow_set[borrow_index].borrowed_place,
153-
place,
154-
places_conflict::PlaceConflictBias::NoOverlap,
155-
);
156-
157-
if places_conflict {
158-
let location_index = self.location_table.mid_index(location);
159-
all_facts.loan_killed_at.push((borrow_index, location_index));
160-
}
123+
local, location
124+
);
125+
126+
if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) {
127+
for &borrow_index in borrow_indices {
128+
let places_conflict = places_conflict::places_conflict(
129+
self.tcx,
130+
self.body,
131+
self.borrow_set[borrow_index].borrowed_place,
132+
place,
133+
places_conflict::PlaceConflictBias::NoOverlap,
134+
);
135+
136+
if places_conflict {
137+
let location_index = self.location_table.mid_index(location);
138+
self.all_facts.loan_killed_at.push((borrow_index, location_index));
161139
}
162140
}
163141
}
164142
}
165143
}
166144
}
167-
}
168145

169-
/// When recording facts for Polonius, records the borrows on the specified local as `killed`.
170-
fn record_killed_borrows_for_local(
171-
all_facts: &mut AllFacts,
172-
borrow_set: &BorrowSet<'_>,
173-
location_table: &LocationTable,
174-
local: Local,
175-
location: Location,
176-
) {
177-
if let Some(borrow_indices) = borrow_set.local_map.get(&local) {
178-
all_facts.loan_killed_at.reserve(borrow_indices.len());
179-
for &borrow_index in borrow_indices {
180-
let location_index = location_table.mid_index(location);
181-
all_facts.loan_killed_at.push((borrow_index, location_index));
146+
/// When recording facts for Polonius, records the borrows on the specified local as `killed`.
147+
fn record_killed_borrows_for_local(&mut self, local: Local, location: Location) {
148+
if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) {
149+
let location_index = self.location_table.mid_index(location);
150+
self.all_facts.loan_killed_at.reserve(borrow_indices.len());
151+
for &borrow_index in borrow_indices {
152+
self.all_facts.loan_killed_at.push((borrow_index, location_index));
153+
}
182154
}
183155
}
184156
}

compiler/rustc_borrowck/src/polonius/mod.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
//! Will be removed in the future, once the in-tree `-Zpolonius=next` implementation reaches feature
44
//! parity.
55
6-
use rustc_infer::infer::InferCtxt;
76
use rustc_middle::mir::{Body, LocalKind, Location, START_BLOCK};
87
use rustc_middle::ty::TyCtxt;
98
use rustc_mir_dataflow::move_paths::{InitKind, InitLocation, MoveData};
@@ -150,11 +149,16 @@ pub(crate) fn emit_loan_invalidations_facts<'tcx>(
150149

151150
/// Emit facts about CFG points and edges, as well as locations where loans are killed.
152151
pub(crate) fn emit_cfg_and_loan_kills_facts<'tcx>(
153-
infcx: &InferCtxt<'tcx>,
152+
tcx: TyCtxt<'tcx>,
154153
all_facts: &mut Option<AllFacts>,
155154
location_table: &LocationTable,
156155
body: &Body<'tcx>,
157156
borrow_set: &BorrowSet<'tcx>,
158157
) {
159-
constraint_generation::generate_constraints(infcx, all_facts, location_table, body, borrow_set);
158+
let Some(all_facts) = all_facts else {
159+
// Nothing to do if we don't have any facts to fill
160+
return;
161+
};
162+
163+
constraint_generation::generate_constraints(tcx, all_facts, location_table, body, borrow_set);
160164
}

0 commit comments

Comments
 (0)