Skip to content

Commit 454f98a

Browse files
committed
Split out all the SCC components into InferredRegions.
Since this collapses `RegionInferenceContext`, `::solve()` now consumes the inference context.
1 parent 2c362f7 commit 454f98a

File tree

19 files changed

+669
-580
lines changed

19 files changed

+669
-580
lines changed

compiler/rustc_borrowck/src/consumers.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,6 @@ pub struct BodyWithBorrowckFacts<'tcx> {
9090
pub promoted: IndexVec<Promoted, Body<'tcx>>,
9191
/// The set of borrows occurring in `body` with data about them.
9292
pub borrow_set: BorrowSet<'tcx>,
93-
/// Context generated during borrowck, intended to be passed to
94-
/// [`calculate_borrows_out_of_scope_at_location`].
95-
pub region_inference_context: RegionInferenceContext<'tcx>,
9693
/// The inferred region values. These are included because they
9794
/// are necessary as input to
9895
/// [`calculate_borrows_out_of_scope_at_location`].

compiler/rustc_borrowck/src/dataflow.rs

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ use rustc_mir_dataflow::{Analysis, GenKill, JoinSemiLattice};
1515
use tracing::debug;
1616

1717
use crate::region_infer::InferredRegions;
18-
use crate::{BorrowSet, PlaceConflictBias, PlaceExt, RegionInferenceContext, places_conflict};
18+
use crate::region_infer::values::LivenessValues;
19+
use crate::{BorrowSet, PlaceConflictBias, PlaceExt, places_conflict};
1920

2021
// This analysis is different to most others. Its results aren't computed with
2122
// `iterate_to_fixpoint`, but are instead composed from the results of three sub-analyses that are
@@ -183,22 +184,19 @@ struct OutOfScopePrecomputer<'a, 'tcx> {
183184
visited: DenseBitSet<mir::BasicBlock>,
184185
visit_stack: Vec<mir::BasicBlock>,
185186
body: &'a Body<'tcx>,
186-
regioncx: &'a RegionInferenceContext<'tcx>,
187187
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
188188
}
189189

190190
impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
191191
fn compute(
192192
body: &Body<'tcx>,
193-
regioncx: &RegionInferenceContext<'tcx>,
194193
scc_values: &InferredRegions<'tcx>,
195194
borrow_set: &BorrowSet<'tcx>,
196195
) -> FxIndexMap<Location, Vec<BorrowIndex>> {
197196
let mut prec = OutOfScopePrecomputer {
198197
visited: DenseBitSet::new_empty(body.basic_blocks.len()),
199198
visit_stack: vec![],
200199
body,
201-
regioncx,
202200
borrows_out_of_scope_at_location: FxIndexMap::default(),
203201
};
204202
for (borrow_index, borrow_data) in borrow_set.iter_enumerated() {
@@ -225,13 +223,9 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
225223
let first_lo = first_location.statement_index;
226224
let first_hi = first_bb_data.statements.len();
227225

228-
if let Some(kill_stmt) = self.regioncx.first_non_contained_inclusive(
229-
scc_values,
230-
borrow_region,
231-
first_block,
232-
first_lo,
233-
first_hi,
234-
) {
226+
if let Some(kill_stmt) =
227+
scc_values.first_non_contained_inclusive(borrow_region, first_block, first_lo, first_hi)
228+
{
235229
let kill_location = Location { block: first_block, statement_index: kill_stmt };
236230
// If region does not contain a point at the location, then add to list and skip
237231
// successor locations.
@@ -258,13 +252,9 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
258252
while let Some(block) = self.visit_stack.pop() {
259253
let bb_data = &self.body[block];
260254
let num_stmts = bb_data.statements.len();
261-
if let Some(kill_stmt) = self.regioncx.first_non_contained_inclusive(
262-
scc_values,
263-
borrow_region,
264-
block,
265-
0,
266-
num_stmts,
267-
) {
255+
if let Some(kill_stmt) =
256+
scc_values.first_non_contained_inclusive(borrow_region, block, 0, num_stmts)
257+
{
268258
let kill_location = Location { block, statement_index: kill_stmt };
269259
// If region does not contain a point at the location, then add to list and skip
270260
// successor locations.
@@ -293,26 +283,24 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
293283
// This is `pub` because it's used by unstable external borrowck data users, see `consumers.rs`.
294284
pub fn calculate_borrows_out_of_scope_at_location<'tcx>(
295285
body: &Body<'tcx>,
296-
regioncx: &RegionInferenceContext<'tcx>,
297286
scc_values: &InferredRegions<'tcx>,
298287
borrow_set: &BorrowSet<'tcx>,
299288
) -> FxIndexMap<Location, Vec<BorrowIndex>> {
300-
OutOfScopePrecomputer::compute(body, regioncx, scc_values, borrow_set)
289+
OutOfScopePrecomputer::compute(body, scc_values, borrow_set)
301290
}
302291

303292
struct PoloniusOutOfScopePrecomputer<'a, 'tcx> {
304293
visited: DenseBitSet<mir::BasicBlock>,
305294
visit_stack: Vec<mir::BasicBlock>,
306295
body: &'a Body<'tcx>,
307-
regioncx: &'a RegionInferenceContext<'tcx>,
308-
296+
liveness_values: &'a LivenessValues,
309297
loans_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
310298
}
311299

312300
impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
313301
fn compute(
314302
body: &Body<'tcx>,
315-
regioncx: &RegionInferenceContext<'tcx>,
303+
liveness_values: &LivenessValues,
316304
borrow_set: &BorrowSet<'tcx>,
317305
) -> FxIndexMap<Location, Vec<BorrowIndex>> {
318306
// The in-tree polonius analysis computes loans going out of scope using the
@@ -321,7 +309,7 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
321309
visited: DenseBitSet::new_empty(body.basic_blocks.len()),
322310
visit_stack: vec![],
323311
body,
324-
regioncx,
312+
liveness_values,
325313
loans_out_of_scope_at_location: FxIndexMap::default(),
326314
};
327315
for (loan_idx, loan_data) in borrow_set.iter_enumerated() {
@@ -421,7 +409,8 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
421409
// Reachability is location-insensitive, and we could take advantage of that, by jumping
422410
// to a further point than just the next statement: we can jump to the furthest point
423411
// within the block where `r` is live.
424-
if self.regioncx.is_loan_live_at(loan_idx, location) {
412+
let point = self.liveness_values.point_from_location(location);
413+
if self.liveness_values.is_loan_live_at(loan_idx, point) {
425414
continue;
426415
}
427416

@@ -438,15 +427,15 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
438427
pub fn new(
439428
tcx: TyCtxt<'tcx>,
440429
body: &'a Body<'tcx>,
441-
regioncx: &RegionInferenceContext<'tcx>,
430+
liveness_values: &'a LivenessValues,
442431
scc_values: &InferredRegions<'tcx>,
443432
borrow_set: &'a BorrowSet<'tcx>,
444433
) -> Self {
445434
let borrows_out_of_scope_at_location =
446435
if !tcx.sess.opts.unstable_opts.polonius.is_next_enabled() {
447-
calculate_borrows_out_of_scope_at_location(body, regioncx, scc_values, borrow_set)
436+
calculate_borrows_out_of_scope_at_location(body, scc_values, borrow_set)
448437
} else {
449-
PoloniusOutOfScopePrecomputer::compute(body, regioncx, borrow_set)
438+
PoloniusOutOfScopePrecomputer::compute(body, liveness_values, borrow_set)
450439
};
451440
Borrows { tcx, body, borrow_set, borrows_out_of_scope_at_location }
452441
}

compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,8 @@ impl<'tcx> TypeOpInfo<'tcx> for crate::type_check::InstantiateOpaqueType<'tcx> {
403403
// started MIR borrowchecking with, so the region
404404
// constraints have already been taken. Use the data from
405405
// our `mbcx` instead.
406-
|vid| RegionVariableOrigin::Nll(mbcx.regioncx.definitions[vid].origin),
407-
|vid| mbcx.regioncx.definitions[vid].universe,
406+
|vid| RegionVariableOrigin::Nll(mbcx.definitions[vid].origin),
407+
|vid| mbcx.definitions[vid].universe,
408408
)
409409
}
410410
}

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3434,7 +3434,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
34343434

34353435
let tcx = self.infcx.tcx;
34363436

3437-
let return_ty = self.regioncx.universal_regions().unnormalized_output_ty;
3437+
let return_ty = self.universal_regions().unnormalized_output_ty;
34383438

34393439
// to avoid panics
34403440
if let Some(iter_trait) = tcx.get_diagnostic_item(sym::Iterator)

compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use super::{RegionName, UseSpans, find_use};
2121
use crate::borrow_set::BorrowData;
2222
use crate::constraints::OutlivesConstraint;
2323
use crate::nll::ConstraintDescription;
24-
use crate::region_infer::{BlameConstraint, Cause};
24+
use crate::region_infer::{BlameConstraint, Cause, ConstraintSearch};
2525
use crate::{MirBorrowckCtxt, WriteKind};
2626

2727
#[derive(Debug)]
@@ -572,14 +572,23 @@ fn suggest_rewrite_if_let<G: EmissionGuarantee>(
572572
}
573573
}
574574

575-
impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
575+
impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
576+
pub(crate) fn constraint_search<'mbc>(&'mbc self) -> ConstraintSearch<'mbc, 'tcx> {
577+
ConstraintSearch {
578+
definitions: self.definitions,
579+
fr_static: self.universal_regions().fr_static,
580+
constraint_graph: &self.constraint_graph,
581+
constraints: &self.outlives_constraints,
582+
}
583+
}
584+
576585
fn free_region_constraint_info(
577586
&self,
578587
borrow_region: RegionVid,
579588
outlived_region: RegionVid,
580589
) -> (ConstraintCategory<'tcx>, bool, Span, Option<RegionName>, Vec<OutlivesConstraint<'tcx>>)
581590
{
582-
let (blame_constraint, path) = self.regioncx.best_blame_constraint(
591+
let (blame_constraint, path) = self.constraint_search().best_blame_constraint(
583592
borrow_region,
584593
NllRegionVariableOrigin::FreeRegion,
585594
outlived_region,
@@ -611,14 +620,17 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
611620
borrow: &BorrowData<'tcx>,
612621
kind_place: Option<(WriteKind, Place<'tcx>)>,
613622
) -> BorrowExplanation<'tcx> {
614-
let regioncx = &self.regioncx;
615623
let body: &Body<'_> = self.body;
616624
let tcx = self.infcx.tcx;
617625

618626
let borrow_region_vid = borrow.region;
619627
debug!(?borrow_region_vid);
620628

621-
let mut region_sub = self.regioncx.find_sub_region_live_at(borrow_region_vid, location);
629+
let mut region_sub = self.constraint_search().find_sub_region_live_at(
630+
&self.liveness_constraints,
631+
borrow_region_vid,
632+
location,
633+
);
622634
debug!(?region_sub);
623635

624636
let mut use_location = location;
@@ -629,13 +641,14 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
629641
// is issued is the same location that invalidates the reference), this is likely a
630642
// loop iteration. In this case, try using the loop terminator location in
631643
// `find_sub_region_live_at`.
632-
if let Some(loop_terminator_location) = self
633-
.scc_values
634-
.find_loop_terminator_location(self.regioncx.scc(borrow.region), body)
644+
if let Some(loop_terminator_location) =
645+
self.scc_values.find_loop_terminator_location(borrow.region, body)
635646
{
636-
region_sub = self
637-
.regioncx
638-
.find_sub_region_live_at(borrow_region_vid, loop_terminator_location);
647+
region_sub = self.constraint_search().find_sub_region_live_at(
648+
&self.liveness_constraints,
649+
borrow_region_vid,
650+
loop_terminator_location,
651+
);
639652
debug!("explain_why_borrow_contains_point: region_sub in loop={:?}", region_sub);
640653
use_location = loop_terminator_location;
641654
use_in_later_iteration_of_loop = true;
@@ -659,7 +672,7 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, 'tcx> {
659672
false
660673
}
661674
};
662-
match find_use::find(body, regioncx, self.scc_values, tcx, region_sub, use_location) {
675+
match find_use::find(body, self.scc_values, tcx, region_sub, use_location) {
663676
Some(Cause::LiveVar(local, location)) if !is_local_boring(local) => {
664677
let span = body.source_info(location).span;
665678
let spans = self

compiler/rustc_borrowck/src/diagnostics/find_use.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,22 @@ use rustc_middle::mir::{self, Body, Local, Location};
66
use rustc_middle::ty::{RegionVid, TyCtxt};
77

88
use crate::def_use::{self, DefUse};
9-
use crate::region_infer::{Cause, InferredRegions, RegionInferenceContext};
9+
use crate::region_infer::{Cause, InferredRegions};
1010

1111
pub(crate) fn find<'tcx>(
1212
body: &Body<'tcx>,
13-
regioncx: &RegionInferenceContext<'tcx>,
1413
scc_values: &InferredRegions<'tcx>,
1514
tcx: TyCtxt<'tcx>,
1615
region_vid: RegionVid,
1716
start_point: Location,
1817
) -> Option<Cause> {
19-
let mut uf =
20-
UseFinder { body, regioncx, tcx, region_vid, start_point, scc_values: &scc_values };
18+
let mut uf = UseFinder { body, tcx, region_vid, start_point, scc_values: &scc_values };
2119

2220
uf.find()
2321
}
2422

2523
struct UseFinder<'a, 'tcx> {
2624
body: &'a Body<'tcx>,
27-
regioncx: &'a RegionInferenceContext<'tcx>,
2825
scc_values: &'a InferredRegions<'tcx>,
2926
tcx: TyCtxt<'tcx>,
3027
region_vid: RegionVid,
@@ -38,7 +35,7 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> {
3835

3936
queue.push_back(self.start_point);
4037
while let Some(p) = queue.pop_front() {
41-
if !self.regioncx.region_contains(self.scc_values, self.region_vid, p) {
38+
if !self.scc_values.region_contains(self.region_vid, p) {
4239
continue;
4340
}
4441

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
667667
let tcx = self.infcx.tcx;
668668
let Some((gat_hir_id, generics)) = path.iter().find_map(|constraint| {
669669
let outlived = constraint.sub;
670-
if let Some(origin) = self.regioncx.definitions.get(outlived)
670+
if let Some(origin) = self.definitions.get(outlived)
671671
&& let NllRegionVariableOrigin::Placeholder(placeholder) = origin.origin
672672
&& let Some(id) = placeholder.bound.kind.get_id()
673673
&& let Some(placeholder_id) = id.as_local()

compiler/rustc_borrowck/src/diagnostics/opaque_types.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ use rustc_trait_selection::errors::impl_trait_overcapture_suggestion;
1616

1717
use crate::MirBorrowckCtxt;
1818
use crate::borrow_set::BorrowData;
19-
use crate::consumers::RegionInferenceContext;
19+
use crate::region_infer::ConstraintSearch;
2020
use crate::region_infer::opaque_types::DeferredOpaqueTypeError;
2121
use crate::type_check::Locations;
22+
use crate::universal_regions::UniversalRegions;
2223

2324
impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
2425
pub(crate) fn report_opaque_type_errors(&mut self, errors: Vec<DeferredOpaqueTypeError<'tcx>>) {
@@ -41,21 +42,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
4142
hidden_type,
4243
member_region,
4344
} => {
44-
let named_ty = self.regioncx.name_regions_for_member_constraint(
45-
self.scc_values,
46-
infcx.tcx,
47-
hidden_type.ty,
48-
);
49-
let named_key = self.regioncx.name_regions_for_member_constraint(
50-
self.scc_values,
51-
infcx.tcx,
52-
opaque_type_key,
53-
);
54-
let named_region = self.regioncx.name_regions_for_member_constraint(
55-
self.scc_values,
56-
infcx.tcx,
57-
member_region,
58-
);
45+
let named_ty =
46+
self.name_regions_for_member_constraint(infcx.tcx, hidden_type.ty);
47+
let named_key =
48+
self.name_regions_for_member_constraint(infcx.tcx, opaque_type_key);
49+
let named_region =
50+
self.name_regions_for_member_constraint(infcx.tcx, member_region);
5951
let diag = unexpected_hidden_region_diagnostic(
6052
infcx,
6153
self.mir_def_id(),
@@ -115,9 +107,10 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
115107
let tcx = self.infcx.tcx;
116108
let ControlFlow::Break((opaque_def_id, offending_region_idx, location)) = ty
117109
.visit_with(&mut FindOpaqueRegion {
118-
regioncx: &self.regioncx,
119110
tcx,
120111
borrow_region: borrow.region,
112+
universal_regions: self.universal_regions(),
113+
constraint_search: self.constraint_search(),
121114
})
122115
else {
123116
continue;
@@ -217,8 +210,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
217210
/// This visitor contains the bulk of the logic for this lint.
218211
struct FindOpaqueRegion<'a, 'tcx> {
219212
tcx: TyCtxt<'tcx>,
220-
regioncx: &'a RegionInferenceContext<'tcx>,
213+
constraint_search: ConstraintSearch<'a, 'tcx>,
221214
borrow_region: ty::RegionVid,
215+
universal_regions: &'a UniversalRegions<'tcx>,
222216
}
223217

224218
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindOpaqueRegion<'_, 'tcx> {
@@ -245,11 +239,11 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for FindOpaqueRegion<'_, 'tcx> {
245239
if opaque_region.is_bound() {
246240
continue;
247241
}
248-
let opaque_region_vid = self.regioncx.to_region_vid(opaque_region);
242+
let opaque_region_vid = self.universal_regions.to_region_vid(opaque_region);
249243

250244
// Find a path between the borrow region and our opaque capture.
251245
if let Some(path) = self
252-
.regioncx
246+
.constraint_search
253247
.constraint_path_between_regions(self.borrow_region, opaque_region_vid)
254248
{
255249
for constraint in path {

0 commit comments

Comments
 (0)