Skip to content

Commit 73c0ae6

Browse files
committed
Auto merge of #135615 - matthiaskrgr:rollup-ra7vftt, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - #131806 (Treat other items as functions for the purpose of type-based search) - #134980 (Location-sensitive polonius prototype: endgame) - #135558 (Detect if-else chains with a missing final else in type errors) - #135594 (fix error for when results in a rustdoc-js test are in the wrong order) - #135601 (Fix suggestion to convert dereference of raw pointer to ref) - #135604 (Expand docs for `E0207` with additional example) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0c2c096 + 1360e76 commit 73c0ae6

File tree

24 files changed

+596
-188
lines changed

24 files changed

+596
-188
lines changed

compiler/rustc_borrowck/src/dataflow.rs

+45-56
Original file line numberDiff line numberDiff line change
@@ -187,19 +187,28 @@ struct OutOfScopePrecomputer<'a, 'tcx> {
187187
borrows_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
188188
}
189189

190-
impl<'a, 'tcx> OutOfScopePrecomputer<'a, 'tcx> {
191-
fn new(body: &'a Body<'tcx>, regioncx: &'a RegionInferenceContext<'tcx>) -> Self {
192-
OutOfScopePrecomputer {
190+
impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
191+
fn compute(
192+
body: &Body<'tcx>,
193+
regioncx: &RegionInferenceContext<'tcx>,
194+
borrow_set: &BorrowSet<'tcx>,
195+
) -> FxIndexMap<Location, Vec<BorrowIndex>> {
196+
let mut prec = OutOfScopePrecomputer {
193197
visited: DenseBitSet::new_empty(body.basic_blocks.len()),
194198
visit_stack: vec![],
195199
body,
196200
regioncx,
197201
borrows_out_of_scope_at_location: FxIndexMap::default(),
202+
};
203+
for (borrow_index, borrow_data) in borrow_set.iter_enumerated() {
204+
let borrow_region = borrow_data.region;
205+
let location = borrow_data.reserve_location;
206+
prec.precompute_borrows_out_of_scope(borrow_index, borrow_region, location);
198207
}
208+
209+
prec.borrows_out_of_scope_at_location
199210
}
200-
}
201211

202-
impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
203212
fn precompute_borrows_out_of_scope(
204213
&mut self,
205214
borrow_index: BorrowIndex,
@@ -280,15 +289,7 @@ pub fn calculate_borrows_out_of_scope_at_location<'tcx>(
280289
regioncx: &RegionInferenceContext<'tcx>,
281290
borrow_set: &BorrowSet<'tcx>,
282291
) -> FxIndexMap<Location, Vec<BorrowIndex>> {
283-
let mut prec = OutOfScopePrecomputer::new(body, regioncx);
284-
for (borrow_index, borrow_data) in borrow_set.iter_enumerated() {
285-
let borrow_region = borrow_data.region;
286-
let location = borrow_data.reserve_location;
287-
288-
prec.precompute_borrows_out_of_scope(borrow_index, borrow_region, location);
289-
}
290-
291-
prec.borrows_out_of_scope_at_location
292+
OutOfScopePrecomputer::compute(body, regioncx, borrow_set)
292293
}
293294

294295
struct PoloniusOutOfScopePrecomputer<'a, 'tcx> {
@@ -300,19 +301,30 @@ struct PoloniusOutOfScopePrecomputer<'a, 'tcx> {
300301
loans_out_of_scope_at_location: FxIndexMap<Location, Vec<BorrowIndex>>,
301302
}
302303

303-
impl<'a, 'tcx> PoloniusOutOfScopePrecomputer<'a, 'tcx> {
304-
fn new(body: &'a Body<'tcx>, regioncx: &'a RegionInferenceContext<'tcx>) -> Self {
305-
Self {
304+
impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
305+
fn compute(
306+
body: &Body<'tcx>,
307+
regioncx: &RegionInferenceContext<'tcx>,
308+
borrow_set: &BorrowSet<'tcx>,
309+
) -> FxIndexMap<Location, Vec<BorrowIndex>> {
310+
// The in-tree polonius analysis computes loans going out of scope using the
311+
// set-of-loans model.
312+
let mut prec = PoloniusOutOfScopePrecomputer {
306313
visited: DenseBitSet::new_empty(body.basic_blocks.len()),
307314
visit_stack: vec![],
308315
body,
309316
regioncx,
310317
loans_out_of_scope_at_location: FxIndexMap::default(),
318+
};
319+
for (loan_idx, loan_data) in borrow_set.iter_enumerated() {
320+
let issuing_region = loan_data.region;
321+
let loan_issued_at = loan_data.reserve_location;
322+
prec.precompute_loans_out_of_scope(loan_idx, issuing_region, loan_issued_at);
311323
}
324+
325+
prec.loans_out_of_scope_at_location
312326
}
313-
}
314327

315-
impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
316328
/// Loans are in scope while they are live: whether they are contained within any live region.
317329
/// In the location-insensitive analysis, a loan will be contained in a region if the issuing
318330
/// region can reach it in the subset graph. So this is a reachability problem.
@@ -325,10 +337,17 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
325337
let sccs = self.regioncx.constraint_sccs();
326338
let universal_regions = self.regioncx.universal_regions();
327339

340+
// The loop below was useful for the location-insensitive analysis but shouldn't be
341+
// impactful in the location-sensitive case. It seems that it does, however, as without it a
342+
// handful of tests fail. That likely means some liveness or outlives data related to choice
343+
// regions is missing
344+
// FIXME: investigate the impact of loans traversing applied member constraints and why some
345+
// tests fail otherwise.
346+
//
328347
// We first handle the cases where the loan doesn't go out of scope, depending on the
329348
// issuing region's successors.
330349
for successor in graph::depth_first_search(&self.regioncx.region_graph(), issuing_region) {
331-
// 1. Via applied member constraints
350+
// Via applied member constraints
332351
//
333352
// The issuing region can flow into the choice regions, and they are either:
334353
// - placeholders or free regions themselves,
@@ -346,14 +365,6 @@ impl<'tcx> PoloniusOutOfScopePrecomputer<'_, 'tcx> {
346365
return;
347366
}
348367
}
349-
350-
// 2. Via regions that are live at all points: placeholders and free regions.
351-
//
352-
// If the issuing region outlives such a region, its loan escapes the function and
353-
// cannot go out of scope. We can early return.
354-
if self.regioncx.is_region_live_at_all_points(successor) {
355-
return;
356-
}
357368
}
358369

359370
let first_block = loan_issued_at.block;
@@ -461,34 +472,12 @@ impl<'a, 'tcx> Borrows<'a, 'tcx> {
461472
regioncx: &RegionInferenceContext<'tcx>,
462473
borrow_set: &'a BorrowSet<'tcx>,
463474
) -> Self {
464-
let mut borrows_out_of_scope_at_location =
465-
calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set);
466-
467-
// The in-tree polonius analysis computes loans going out of scope using the set-of-loans
468-
// model, and makes sure they're identical to the existing computation of the set-of-points
469-
// model.
470-
if tcx.sess.opts.unstable_opts.polonius.is_next_enabled() {
471-
let mut polonius_prec = PoloniusOutOfScopePrecomputer::new(body, regioncx);
472-
for (loan_idx, loan_data) in borrow_set.iter_enumerated() {
473-
let issuing_region = loan_data.region;
474-
let loan_issued_at = loan_data.reserve_location;
475-
476-
polonius_prec.precompute_loans_out_of_scope(
477-
loan_idx,
478-
issuing_region,
479-
loan_issued_at,
480-
);
481-
}
482-
483-
assert_eq!(
484-
borrows_out_of_scope_at_location, polonius_prec.loans_out_of_scope_at_location,
485-
"polonius loan scopes differ from NLL borrow scopes, for body {:?}",
486-
body.span,
487-
);
488-
489-
borrows_out_of_scope_at_location = polonius_prec.loans_out_of_scope_at_location;
490-
}
491-
475+
let borrows_out_of_scope_at_location =
476+
if !tcx.sess.opts.unstable_opts.polonius.is_next_enabled() {
477+
calculate_borrows_out_of_scope_at_location(body, regioncx, borrow_set)
478+
} else {
479+
PoloniusOutOfScopePrecomputer::compute(body, regioncx, borrow_set)
480+
};
492481
Borrows { tcx, body, borrow_set, borrows_out_of_scope_at_location }
493482
}
494483

compiler/rustc_borrowck/src/nll.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ pub(crate) fn compute_regions<'a, 'tcx>(
103103
constraints,
104104
universal_region_relations,
105105
opaque_type_values,
106-
mut polonius_context,
106+
polonius_context,
107107
} = type_check::type_check(
108108
infcx,
109109
body,
@@ -142,10 +142,10 @@ pub(crate) fn compute_regions<'a, 'tcx>(
142142
location_map,
143143
);
144144

145-
// If requested for `-Zpolonius=next`, convert NLL constraints to localized outlives
146-
// constraints.
147-
let localized_outlives_constraints = polonius_context.as_mut().map(|polonius_context| {
148-
polonius_context.create_localized_constraints(infcx.tcx, &regioncx, body)
145+
// If requested for `-Zpolonius=next`, convert NLL constraints to localized outlives constraints
146+
// and use them to compute loan liveness.
147+
let localized_outlives_constraints = polonius_context.as_ref().map(|polonius_context| {
148+
polonius_context.compute_loan_liveness(infcx.tcx, &mut regioncx, body, borrow_set)
149149
});
150150

151151
// If requested: dump NLL facts, and run legacy polonius analysis.

0 commit comments

Comments
 (0)