Skip to content

Commit e574083

Browse files
Auto merge of #113382 - lqd:test-mcp510, r=<try>
[perf] test MCP510 r? `@ghost`
2 parents d9ca9bd + 55927af commit e574083

15 files changed

+156
-197
lines changed

compiler/rustc_borrowck/src/polonius/liveness_constraints.rs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,22 +105,14 @@ fn propagate_loans_between_points(
105105
});
106106
}
107107

108-
let Some(current_live_regions) = live_regions.row(current_point) else {
109-
// There are no constraints to add: there are no live regions at the current point.
110-
return;
111-
};
112108
let Some(next_live_regions) = live_regions.row(next_point) else {
113109
// There are no constraints to add: there are no live regions at the next point.
114110
return;
115111
};
116112

117113
for region in next_live_regions.iter() {
118-
if !current_live_regions.contains(region) {
119-
continue;
120-
}
121-
122-
// `region` is indeed live at both points, add a constraint between them, according to
123-
// variance.
114+
// `region` could be live at the current point, and is live at the next point: add a
115+
// constraint between them, according to variance.
124116
if let Some(&direction) = live_region_variances.get(&region) {
125117
add_liveness_constraint(
126118
region,
Lines changed: 5 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,25 @@
1-
use std::collections::{BTreeMap, BTreeSet};
2-
31
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
4-
use rustc_middle::mir::visit::Visitor;
5-
use rustc_middle::mir::{
6-
Body, Local, Location, Place, Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
7-
};
8-
use rustc_middle::ty::{RegionVid, TyCtxt};
2+
use rustc_middle::ty::RegionVid;
93
use rustc_mir_dataflow::points::PointIndex;
104

115
use super::{LiveLoans, LocalizedOutlivesConstraintSet};
6+
use crate::BorrowSet;
127
use crate::constraints::OutlivesConstraint;
13-
use crate::dataflow::BorrowIndex;
148
use crate::region_infer::values::LivenessValues;
159
use crate::type_check::Locations;
16-
use crate::{BorrowSet, PlaceConflictBias, places_conflict};
1710

1811
/// Compute loan reachability, stop at kills, and trace loan liveness throughout the CFG, by
1912
/// traversing the full graph of constraints that combines:
2013
/// - the localized constraints (the physical edges),
2114
/// - with the constraints that hold at all points (the logical edges).
2215
pub(super) fn compute_loan_liveness<'tcx>(
23-
tcx: TyCtxt<'tcx>,
24-
body: &Body<'tcx>,
2516
liveness: &LivenessValues,
2617
outlives_constraints: impl Iterator<Item = OutlivesConstraint<'tcx>>,
2718
borrow_set: &BorrowSet<'tcx>,
2819
localized_outlives_constraints: &LocalizedOutlivesConstraintSet,
2920
) -> LiveLoans {
3021
let mut live_loans = LiveLoans::new(borrow_set.len());
3122

32-
// FIXME: it may be preferable for kills to be encoded in the edges themselves, to simplify and
33-
// likely make traversal (and constraint generation) more efficient. We also display kills on
34-
// edges when visualizing the constraint graph anyways.
35-
let kills = collect_kills(body, tcx, borrow_set);
36-
3723
// Create the full graph with the physical edges we've localized earlier, and the logical edges
3824
// of constraints that hold at all points.
3925
let logical_constraints =
@@ -60,7 +46,9 @@ pub(super) fn compute_loan_liveness<'tcx>(
6046
}
6147

6248
// Record the loan as being live on entry to this point.
63-
live_loans.insert(node.point, loan_idx);
49+
if liveness.is_live_at(node.region, liveness.location_from_point(node.point)) {
50+
live_loans.insert(node.point, loan_idx);
51+
}
6452

6553
// Here, we have a conundrum. There's currently a weakness in our theory, in that
6654
// we're using a single notion of reachability to represent what used to be _two_
@@ -111,21 +99,7 @@ pub(super) fn compute_loan_liveness<'tcx>(
11199
// borrowck implementation in a-mir-formality, fuzzing, or manually crafting
112100
// counter-examples.
113101

114-
// Continuing traversal will depend on whether the loan is killed at this point, and
115-
// whether we're time-traveling.
116-
let current_location = liveness.location_from_point(node.point);
117-
let is_loan_killed =
118-
kills.get(&current_location).is_some_and(|kills| kills.contains(&loan_idx));
119-
120102
for succ in graph.outgoing_edges(node) {
121-
// If the loan is killed at this point, it is killed _on exit_. But only during
122-
// forward traversal.
123-
if is_loan_killed {
124-
let destination = liveness.location_from_point(succ.point);
125-
if current_location.is_predecessor_of(destination, body) {
126-
continue;
127-
}
128-
}
129103
stack.push(succ);
130104
}
131105
}
@@ -192,116 +166,3 @@ impl LocalizedConstraintGraph {
192166
physical_edges.chain(materialized_edges)
193167
}
194168
}
195-
196-
/// Traverses the MIR and collects kills.
197-
fn collect_kills<'tcx>(
198-
body: &Body<'tcx>,
199-
tcx: TyCtxt<'tcx>,
200-
borrow_set: &BorrowSet<'tcx>,
201-
) -> BTreeMap<Location, BTreeSet<BorrowIndex>> {
202-
let mut collector = KillsCollector { borrow_set, tcx, body, kills: BTreeMap::default() };
203-
for (block, data) in body.basic_blocks.iter_enumerated() {
204-
collector.visit_basic_block_data(block, data);
205-
}
206-
collector.kills
207-
}
208-
209-
struct KillsCollector<'a, 'tcx> {
210-
body: &'a Body<'tcx>,
211-
tcx: TyCtxt<'tcx>,
212-
borrow_set: &'a BorrowSet<'tcx>,
213-
214-
/// The set of loans killed at each location.
215-
kills: BTreeMap<Location, BTreeSet<BorrowIndex>>,
216-
}
217-
218-
// This visitor has a similar structure to the `Borrows` dataflow computation with respect to kills,
219-
// and the datalog polonius fact generation for the `loan_killed_at` relation.
220-
impl<'tcx> KillsCollector<'_, 'tcx> {
221-
/// Records the borrows on the specified place as `killed`. For example, when assigning to a
222-
/// local, or on a call's return destination.
223-
fn record_killed_borrows_for_place(&mut self, place: Place<'tcx>, location: Location) {
224-
// For the reasons described in graph traversal, we also filter out kills
225-
// unreachable from the loan's introduction point, as they would stop traversal when
226-
// e.g. checking for reachability in the subset graph through invariance constraints
227-
// higher up.
228-
let filter_unreachable_kills = |loan| {
229-
let introduction = self.borrow_set[loan].reserve_location;
230-
let reachable = introduction.is_predecessor_of(location, self.body);
231-
reachable
232-
};
233-
234-
let other_borrows_of_local = self
235-
.borrow_set
236-
.local_map
237-
.get(&place.local)
238-
.into_iter()
239-
.flat_map(|bs| bs.iter())
240-
.copied();
241-
242-
// If the borrowed place is a local with no projections, all other borrows of this
243-
// local must conflict. This is purely an optimization so we don't have to call
244-
// `places_conflict` for every borrow.
245-
if place.projection.is_empty() {
246-
if !self.body.local_decls[place.local].is_ref_to_static() {
247-
self.kills
248-
.entry(location)
249-
.or_default()
250-
.extend(other_borrows_of_local.filter(|&loan| filter_unreachable_kills(loan)));
251-
}
252-
return;
253-
}
254-
255-
// By passing `PlaceConflictBias::NoOverlap`, we conservatively assume that any given
256-
// pair of array indices are not equal, so that when `places_conflict` returns true, we
257-
// will be assured that two places being compared definitely denotes the same sets of
258-
// locations.
259-
let definitely_conflicting_borrows = other_borrows_of_local
260-
.filter(|&i| {
261-
places_conflict(
262-
self.tcx,
263-
self.body,
264-
self.borrow_set[i].borrowed_place,
265-
place,
266-
PlaceConflictBias::NoOverlap,
267-
)
268-
})
269-
.filter(|&loan| filter_unreachable_kills(loan));
270-
271-
self.kills.entry(location).or_default().extend(definitely_conflicting_borrows);
272-
}
273-
274-
/// Records the borrows on the specified local as `killed`.
275-
fn record_killed_borrows_for_local(&mut self, local: Local, location: Location) {
276-
if let Some(borrow_indices) = self.borrow_set.local_map.get(&local) {
277-
self.kills.entry(location).or_default().extend(borrow_indices.iter());
278-
}
279-
}
280-
}
281-
282-
impl<'tcx> Visitor<'tcx> for KillsCollector<'_, 'tcx> {
283-
fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
284-
// Make sure there are no remaining borrows for locals that have gone out of scope.
285-
if let StatementKind::StorageDead(local) = statement.kind {
286-
self.record_killed_borrows_for_local(local, location);
287-
}
288-
289-
self.super_statement(statement, location);
290-
}
291-
292-
fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, location: Location) {
293-
// When we see `X = ...`, then kill borrows of `(*X).foo` and so forth.
294-
self.record_killed_borrows_for_place(*place, location);
295-
self.super_assign(place, rvalue, location);
296-
}
297-
298-
fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
299-
// A `Call` terminator's return value can be a local which has borrows, so we need to record
300-
// those as killed as well.
301-
if let TerminatorKind::Call { destination, .. } = terminator.kind {
302-
self.record_killed_borrows_for_place(destination, location);
303-
}
304-
305-
self.super_terminator(terminator, location);
306-
}
307-
}

compiler/rustc_borrowck/src/polonius/mod.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,6 @@ impl PoloniusContext {
182182
// Now that we have a complete graph, we can compute reachability to trace the liveness of
183183
// loans for the next step in the chain, the NLL loan scope and active loans computations.
184184
let live_loans = compute_loan_liveness(
185-
tcx,
186-
body,
187185
regioncx.liveness_constraints(),
188186
regioncx.outlives_constraints(),
189187
borrow_set,

compiler/rustc_borrowck/src/polonius/typeck_constraints.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ pub(super) fn convert_typeck_constraints<'tcx>(
4747
tcx,
4848
body,
4949
stmt,
50-
liveness,
5150
&outlives_constraint,
52-
location,
5351
point,
5452
universal_regions,
5553
)
@@ -78,9 +76,7 @@ fn localize_statement_constraint<'tcx>(
7876
tcx: TyCtxt<'tcx>,
7977
body: &Body<'tcx>,
8078
stmt: &Statement<'tcx>,
81-
liveness: &LivenessValues,
8279
outlives_constraint: &OutlivesConstraint<'tcx>,
83-
current_location: Location,
8480
current_point: PointIndex,
8581
universal_regions: &UniversalRegions<'tcx>,
8682
) -> LocalizedOutlivesConstraint {
@@ -119,16 +115,8 @@ fn localize_statement_constraint<'tcx>(
119115
"there should be no common regions between the LHS and RHS of an assignment"
120116
);
121117

122-
// As mentioned earlier, we should be tracking these better upstream but: we want to
123-
// relate the types on entry to the type of the place on exit. That is, outlives
124-
// constraints on the RHS are on entry, and outlives constraints to/from the LHS are on
125-
// exit (i.e. on entry to the successor location).
126118
let lhs_ty = body.local_decls[lhs.local].ty;
127-
let successor_location = Location {
128-
block: current_location.block,
129-
statement_index: current_location.statement_index + 1,
130-
};
131-
let successor_point = liveness.point_from_location(successor_location);
119+
let successor_point = current_point;
132120
compute_constraint_direction(
133121
tcx,
134122
outlives_constraint,

compiler/rustc_session/src/config.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3385,13 +3385,13 @@ impl PatchableFunctionEntry {
33853385
#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
33863386
pub enum Polonius {
33873387
/// The default value: disabled.
3388-
#[default]
33893388
Off,
33903389

33913390
/// Legacy version, using datalog and the `polonius-engine` crate. Historical value for `-Zpolonius`.
33923391
Legacy,
33933392

33943393
/// In-tree prototype, extending the NLL infrastructure.
3394+
#[default]
33953395
Next,
33963396
}
33973397

src/tools/compiletest/src/runtest.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1645,7 +1645,7 @@ impl<'test> TestCx<'test> {
16451645

16461646
match self.config.compare_mode {
16471647
Some(CompareMode::Polonius) => {
1648-
rustc.args(&["-Zpolonius"]);
1648+
rustc.args(&["-Zpolonius=next"]);
16491649
}
16501650
Some(CompareMode::NextSolver) => {
16511651
rustc.args(&["-Znext-solver"]);

tests/crashes/135646.rs

Lines changed: 0 additions & 7 deletions
This file was deleted.

tests/ui/drop/dropck-normalize-errors.stderr renamed to tests/ui/drop/dropck-normalize-errors.nll.stderr

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,44 @@
11
error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `ADecoder<'a>`
2-
--> $DIR/dropck-normalize-errors.rs:15:28
2+
--> $DIR/dropck-normalize-errors.rs:19:28
33
|
44
LL | fn make_a_decoder<'a>() -> ADecoder<'a> {
55
| ^^^^^^^^^^^^ within `ADecoder<'a>`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
66
|
77
help: this trait has no implementations, consider adding one
8-
--> $DIR/dropck-normalize-errors.rs:7:1
8+
--> $DIR/dropck-normalize-errors.rs:11:1
99
|
1010
LL | trait NonImplementedTrait {
1111
| ^^^^^^^^^^^^^^^^^^^^^^^^^
1212
note: required because it appears within the type `BDecoder`
13-
--> $DIR/dropck-normalize-errors.rs:26:12
13+
--> $DIR/dropck-normalize-errors.rs:30:12
1414
|
1515
LL | pub struct BDecoder {
1616
| ^^^^^^^^
1717
note: required because it appears within the type `ADecoder<'a>`
18-
--> $DIR/dropck-normalize-errors.rs:12:12
18+
--> $DIR/dropck-normalize-errors.rs:16:12
1919
|
2020
LL | pub struct ADecoder<'a> {
2121
| ^^^^^^^^
2222
= note: the return type of a function must have a statically known size
2323

2424
error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied in `BDecoder`
25-
--> $DIR/dropck-normalize-errors.rs:23:20
25+
--> $DIR/dropck-normalize-errors.rs:27:20
2626
|
2727
LL | type Decoder = BDecoder;
2828
| ^^^^^^^^ within `BDecoder`, the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
2929
|
3030
help: this trait has no implementations, consider adding one
31-
--> $DIR/dropck-normalize-errors.rs:7:1
31+
--> $DIR/dropck-normalize-errors.rs:11:1
3232
|
3333
LL | trait NonImplementedTrait {
3434
| ^^^^^^^^^^^^^^^^^^^^^^^^^
3535
note: required because it appears within the type `BDecoder`
36-
--> $DIR/dropck-normalize-errors.rs:26:12
36+
--> $DIR/dropck-normalize-errors.rs:30:12
3737
|
3838
LL | pub struct BDecoder {
3939
| ^^^^^^^^
4040
note: required by a bound in `Decode::Decoder`
41-
--> $DIR/dropck-normalize-errors.rs:4:5
41+
--> $DIR/dropck-normalize-errors.rs:8:5
4242
|
4343
LL | type Decoder;
4444
| ^^^^^^^^^^^^^ required by this bound in `Decode::Decoder`
@@ -48,25 +48,25 @@ LL | type Decoder: ?Sized;
4848
| ++++++++
4949

5050
error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied
51-
--> $DIR/dropck-normalize-errors.rs:27:22
51+
--> $DIR/dropck-normalize-errors.rs:31:22
5252
|
5353
LL | non_implemented: <NonImplementedStruct as NonImplementedTrait>::Assoc,
5454
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
5555
|
5656
help: this trait has no implementations, consider adding one
57-
--> $DIR/dropck-normalize-errors.rs:7:1
57+
--> $DIR/dropck-normalize-errors.rs:11:1
5858
|
5959
LL | trait NonImplementedTrait {
6060
| ^^^^^^^^^^^^^^^^^^^^^^^^^
6161

6262
error[E0277]: the trait bound `NonImplementedStruct: NonImplementedTrait` is not satisfied
63-
--> $DIR/dropck-normalize-errors.rs:15:28
63+
--> $DIR/dropck-normalize-errors.rs:19:28
6464
|
6565
LL | fn make_a_decoder<'a>() -> ADecoder<'a> {
6666
| ^^^^^^^^^^^^ the trait `NonImplementedTrait` is not implemented for `NonImplementedStruct`
6767
|
6868
help: this trait has no implementations, consider adding one
69-
--> $DIR/dropck-normalize-errors.rs:7:1
69+
--> $DIR/dropck-normalize-errors.rs:11:1
7070
|
7171
LL | trait NonImplementedTrait {
7272
| ^^^^^^^^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)