Skip to content

Commit 9eef43a

Browse files
committed
address review comments
push constraint creation to where the statement/terminator info is gathered
1 parent 9d444c2 commit 9eef43a

File tree

1 file changed

+68
-62
lines changed

1 file changed

+68
-62
lines changed

compiler/rustc_borrowck/src/polonius/typeck_constraints.rs

+68-62
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_data_structures::fx::FxHashSet;
22
use rustc_middle::mir::{Body, Location, Statement, StatementKind, Terminator, TerminatorKind};
3-
use rustc_middle::ty::{TyCtxt, TypeVisitable};
3+
use rustc_middle::ty::TyCtxt;
44
use rustc_mir_dataflow::points::PointIndex;
55

66
use super::{LocalizedOutlivesConstraint, LocalizedOutlivesConstraintSet};
@@ -52,10 +52,8 @@ pub(super) fn convert_typeck_constraints<'tcx>(
5252
// this information better in MIR typeck instead, for example with a new `Locations`
5353
// variant that contains which node is crossing over between entry and exit.
5454
let point = liveness.point_from_location(location);
55-
let (from, to) = if let Some(stmt) =
56-
body[location.block].statements.get(location.statement_index)
57-
{
58-
localize_statement_constraint(
55+
if let Some(stmt) = body[location.block].statements.get(location.statement_index) {
56+
convert_statement_constraint(
5957
tcx,
6058
body,
6159
stmt,
@@ -64,34 +62,30 @@ pub(super) fn convert_typeck_constraints<'tcx>(
6462
location,
6563
point,
6664
universal_regions,
65+
localized_outlives_constraints,
6766
)
6867
} else {
6968
assert_eq!(location.statement_index, body[location.block].statements.len());
7069
let terminator = body[location.block].terminator();
71-
localize_terminator_constraint(
70+
convert_terminator_constraint(
7271
tcx,
7372
body,
7473
terminator,
7574
liveness,
7675
&outlives_constraint,
7776
point,
7877
universal_regions,
78+
localized_outlives_constraints,
7979
)
80-
};
81-
localized_outlives_constraints.push(LocalizedOutlivesConstraint {
82-
source: outlives_constraint.sup,
83-
from,
84-
target: outlives_constraint.sub,
85-
to,
86-
});
80+
}
8781
}
8882
}
8983
}
9084
}
9185

9286
/// For a given outlives constraint arising from a MIR statement, computes the CFG `from`-`to`
9387
/// intra-block nodes to localize the constraint.
94-
fn localize_statement_constraint<'tcx>(
88+
fn convert_statement_constraint<'tcx>(
9589
tcx: TyCtxt<'tcx>,
9690
body: &Body<'tcx>,
9791
stmt: &Statement<'tcx>,
@@ -100,7 +94,8 @@ fn localize_statement_constraint<'tcx>(
10094
current_location: Location,
10195
current_point: PointIndex,
10296
universal_regions: &UniversalRegions<'tcx>,
103-
) -> (PointIndex, PointIndex) {
97+
localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet,
98+
) {
10499
match &stmt.kind {
105100
StatementKind::Assign(box (lhs, rhs)) => {
106101
// To create localized outlives constraints without midpoints, we rely on the property
@@ -146,33 +141,52 @@ fn localize_statement_constraint<'tcx>(
146141
statement_index: current_location.statement_index + 1,
147142
};
148143
let successor_point = liveness.point_from_location(successor_location);
149-
compute_constraint_direction(
150-
tcx,
151-
outlives_constraint,
152-
&lhs_ty,
153-
current_point,
154-
successor_point,
155-
universal_regions,
156-
)
144+
145+
let mut from = current_point;
146+
let mut to = current_point;
147+
tcx.for_each_free_region(&lhs_ty, |region| {
148+
let region = universal_regions.to_region_vid(region);
149+
if region == outlives_constraint.sub {
150+
// This constraint flows into the LHS, its effects start becoming visible on
151+
// exit.
152+
to = successor_point;
153+
} else if region == outlives_constraint.sup {
154+
// This constraint flows from the LHS, its effects start becoming visible on
155+
// exit.
156+
from = successor_point;
157+
}
158+
});
159+
localized_outlives_constraints.push(LocalizedOutlivesConstraint {
160+
source: outlives_constraint.sup,
161+
from,
162+
target: outlives_constraint.sub,
163+
to,
164+
});
157165
}
158166
_ => {
159167
// For the other cases, we localize an outlives constraint to where it arises.
160-
(current_point, current_point)
168+
localized_outlives_constraints.push(LocalizedOutlivesConstraint {
169+
source: outlives_constraint.sup,
170+
from: current_point,
171+
target: outlives_constraint.sub,
172+
to: current_point,
173+
});
161174
}
162175
}
163176
}
164177

165178
/// For a given outlives constraint arising from a MIR terminator, computes the CFG `from`-`to`
166179
/// inter-block nodes to localize the constraint.
167-
fn localize_terminator_constraint<'tcx>(
180+
fn convert_terminator_constraint<'tcx>(
168181
tcx: TyCtxt<'tcx>,
169182
body: &Body<'tcx>,
170183
terminator: &Terminator<'tcx>,
171184
liveness: &LivenessValues,
172185
outlives_constraint: &OutlivesConstraint<'tcx>,
173186
current_point: PointIndex,
174187
universal_regions: &UniversalRegions<'tcx>,
175-
) -> (PointIndex, PointIndex) {
188+
localized_outlives_constraints: &mut LocalizedOutlivesConstraintSet,
189+
) {
176190
// FIXME: check if other terminators need the same handling as `Call`s, in particular
177191
// Assert/Yield/Drop. A handful of tests are failing with Drop related issues, as well as some
178192
// coroutine tests, and that may be why.
@@ -185,47 +199,39 @@ fn localize_terminator_constraint<'tcx>(
185199
let destination_ty = destination.ty(&body.local_decls, tcx);
186200
let successor_location = Location { block: *target, statement_index: 0 };
187201
let successor_point = liveness.point_from_location(successor_location);
188-
compute_constraint_direction(
189-
tcx,
190-
outlives_constraint,
191-
&destination_ty,
192-
current_point,
193-
successor_point,
194-
universal_regions,
195-
)
202+
203+
let mut from = current_point;
204+
let mut to = current_point;
205+
tcx.for_each_free_region(&destination_ty, |region| {
206+
let region = universal_regions.to_region_vid(region);
207+
if region == outlives_constraint.sub {
208+
// This constraint flows into the destination, its effects start becoming
209+
// visible on exit.
210+
to = successor_point;
211+
} else if region == outlives_constraint.sup {
212+
// This constraint flows from the destination, its effects start becoming
213+
// visible on exit.
214+
from = successor_point;
215+
}
216+
});
217+
218+
localized_outlives_constraints.push(LocalizedOutlivesConstraint {
219+
source: outlives_constraint.sup,
220+
from,
221+
target: outlives_constraint.sub,
222+
to,
223+
});
196224
}
197225
_ => {
198226
// Typeck constraints guide loans between regions at the current point, so we do that in
199227
// the general case, and liveness will take care of making them flow to the terminator's
200228
// successors.
201-
(current_point, current_point)
229+
localized_outlives_constraints.push(LocalizedOutlivesConstraint {
230+
source: outlives_constraint.sup,
231+
from: current_point,
232+
target: outlives_constraint.sub,
233+
to: current_point,
234+
});
202235
}
203236
}
204237
}
205-
206-
/// For a given constraint, returns the `from`-`to` edge according to whether the constraint flows
207-
/// to or from a free region in the given `value`, some kind of result for an effectful operation,
208-
/// like the LHS of an assignment.
209-
fn compute_constraint_direction<'tcx>(
210-
tcx: TyCtxt<'tcx>,
211-
outlives_constraint: &OutlivesConstraint<'tcx>,
212-
value: &impl TypeVisitable<TyCtxt<'tcx>>,
213-
current_point: PointIndex,
214-
successor_point: PointIndex,
215-
universal_regions: &UniversalRegions<'tcx>,
216-
) -> (PointIndex, PointIndex) {
217-
let mut to = current_point;
218-
let mut from = current_point;
219-
tcx.for_each_free_region(value, |region| {
220-
let region = universal_regions.to_region_vid(region);
221-
if region == outlives_constraint.sub {
222-
// This constraint flows into the result, its effects start becoming visible on exit.
223-
to = successor_point;
224-
} else if region == outlives_constraint.sup {
225-
// This constraint flows from the result, its effects start becoming visible on exit.
226-
from = successor_point;
227-
}
228-
});
229-
230-
(from, to)
231-
}

0 commit comments

Comments
 (0)