Skip to content

Commit 9765858

Browse files
authored
Unrolled build for rust-lang#139666
Rollup merge of rust-lang#139666 - lcnr:pre-revealing-use-cleanup, r=compiler-errors cleanup `mir_borrowck` Cleanup pulled out of rust-lang#139587. Best reviewed commit by commit. r? compiler-errors
2 parents f836ae4 + 420390c commit 9765858

File tree

11 files changed

+108
-154
lines changed

11 files changed

+108
-154
lines changed

Diff for: compiler/rustc_borrowck/src/lib.rs

+63-84
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use std::cell::RefCell;
2121
use std::marker::PhantomData;
2222
use std::ops::{ControlFlow, Deref};
2323

24+
use borrow_set::LocalsStateAtExit;
2425
use root_cx::BorrowCheckRootCtxt;
2526
use rustc_abi::FieldIdx;
2627
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
@@ -303,33 +304,13 @@ fn do_mir_borrowck<'tcx>(
303304
root_cx.set_tainted_by_errors(e);
304305
}
305306

306-
let mut local_names = IndexVec::from_elem(None, &input_body.local_decls);
307-
for var_debug_info in &input_body.var_debug_info {
308-
if let VarDebugInfoContents::Place(place) = var_debug_info.value {
309-
if let Some(local) = place.as_local() {
310-
if let Some(prev_name) = local_names[local]
311-
&& var_debug_info.name != prev_name
312-
{
313-
span_bug!(
314-
var_debug_info.source_info.span,
315-
"local {:?} has many names (`{}` vs `{}`)",
316-
local,
317-
prev_name,
318-
var_debug_info.name
319-
);
320-
}
321-
local_names[local] = Some(var_debug_info.name);
322-
}
323-
}
324-
}
325-
326307
// Replace all regions with fresh inference variables. This
327308
// requires first making our own copy of the MIR. This copy will
328309
// be modified (in place) to contain non-lexical lifetimes. It
329310
// will have a lifetime tied to the inference context.
330311
let mut body_owned = input_body.clone();
331312
let mut promoted = input_promoted.to_owned();
332-
let free_regions = nll::replace_regions_in_mir(&infcx, &mut body_owned, &mut promoted);
313+
let universal_regions = nll::replace_regions_in_mir(&infcx, &mut body_owned, &mut promoted);
333314
let body = &body_owned; // no further changes
334315

335316
let location_table = PoloniusLocationTable::new(body);
@@ -354,7 +335,7 @@ fn do_mir_borrowck<'tcx>(
354335
} = nll::compute_regions(
355336
root_cx,
356337
&infcx,
357-
free_regions,
338+
universal_regions,
358339
body,
359340
&promoted,
360341
&location_table,
@@ -367,24 +348,23 @@ fn do_mir_borrowck<'tcx>(
367348
// Dump MIR results into a file, if that is enabled. This lets us
368349
// write unit-tests, as well as helping with debugging.
369350
nll::dump_nll_mir(&infcx, body, &regioncx, &opt_closure_req, &borrow_set);
351+
polonius::dump_polonius_mir(
352+
&infcx,
353+
body,
354+
&regioncx,
355+
&opt_closure_req,
356+
&borrow_set,
357+
polonius_diagnostics.as_ref(),
358+
);
370359

371360
// We also have a `#[rustc_regions]` annotation that causes us to dump
372361
// information.
373-
let diags_buffer = &mut BorrowckDiagnosticsBuffer::default();
374-
nll::dump_annotation(&infcx, body, &regioncx, &opt_closure_req, diags_buffer);
375-
376-
let movable_coroutine =
377-
// The first argument is the coroutine type passed by value
378-
if let Some(local) = body.local_decls.raw.get(1)
379-
// Get the interior types and args which typeck computed
380-
&& let ty::Coroutine(def_id, _) = *local.ty.kind()
381-
&& tcx.coroutine_movability(def_id) == hir::Movability::Movable
382-
{
383-
true
384-
} else {
385-
false
386-
};
362+
nll::dump_annotation(&infcx, body, &regioncx, &opt_closure_req);
387363

364+
let movable_coroutine = body.coroutine.is_some()
365+
&& tcx.coroutine_movability(def.to_def_id()) == hir::Movability::Movable;
366+
367+
let diags_buffer = &mut BorrowckDiagnosticsBuffer::default();
388368
// While promoteds should mostly be correct by construction, we need to check them for
389369
// invalid moves to detect moving out of arrays:`struct S; fn main() { &([S][0]); }`.
390370
for promoted_body in &promoted {
@@ -402,7 +382,6 @@ fn do_mir_borrowck<'tcx>(
402382
location_table: &location_table,
403383
movable_coroutine,
404384
fn_self_span_reported: Default::default(),
405-
locals_are_invalidated_at_exit,
406385
access_place_error_reported: Default::default(),
407386
reservation_error_reported: Default::default(),
408387
uninitialized_error_reported: Default::default(),
@@ -434,14 +413,33 @@ fn do_mir_borrowck<'tcx>(
434413
promoted_mbcx.report_move_errors();
435414
}
436415

416+
let mut local_names = IndexVec::from_elem(None, &body.local_decls);
417+
for var_debug_info in &body.var_debug_info {
418+
if let VarDebugInfoContents::Place(place) = var_debug_info.value {
419+
if let Some(local) = place.as_local() {
420+
if let Some(prev_name) = local_names[local]
421+
&& var_debug_info.name != prev_name
422+
{
423+
span_bug!(
424+
var_debug_info.source_info.span,
425+
"local {:?} has many names (`{}` vs `{}`)",
426+
local,
427+
prev_name,
428+
var_debug_info.name
429+
);
430+
}
431+
local_names[local] = Some(var_debug_info.name);
432+
}
433+
}
434+
}
435+
437436
let mut mbcx = MirBorrowckCtxt {
438437
root_cx,
439438
infcx: &infcx,
440439
body,
441440
move_data: &move_data,
442441
location_table: &location_table,
443442
movable_coroutine,
444-
locals_are_invalidated_at_exit,
445443
fn_self_span_reported: Default::default(),
446444
access_place_error_reported: Default::default(),
447445
reservation_error_reported: Default::default(),
@@ -454,9 +452,9 @@ fn do_mir_borrowck<'tcx>(
454452
local_names,
455453
region_names: RefCell::default(),
456454
next_region_name: RefCell::new(1),
457-
polonius_output,
458455
move_errors: Vec::new(),
459456
diags_buffer,
457+
polonius_output: polonius_output.as_deref(),
460458
polonius_diagnostics: polonius_diagnostics.as_ref(),
461459
};
462460

@@ -473,16 +471,6 @@ fn do_mir_borrowck<'tcx>(
473471

474472
mbcx.report_move_errors();
475473

476-
// If requested, dump polonius MIR.
477-
polonius::dump_polonius_mir(
478-
&infcx,
479-
body,
480-
&regioncx,
481-
&borrow_set,
482-
polonius_diagnostics.as_ref(),
483-
&opt_closure_req,
484-
);
485-
486474
// For each non-user used mutable variable, check if it's been assigned from
487475
// a user-declared local. If so, then put that local into the used_mut set.
488476
// Note that this set is expected to be small - only upvars from closures
@@ -513,15 +501,14 @@ fn do_mir_borrowck<'tcx>(
513501
};
514502

515503
let body_with_facts = if consumer_options.is_some() {
516-
let output_facts = mbcx.polonius_output;
517504
Some(Box::new(BodyWithBorrowckFacts {
518505
body: body_owned,
519506
promoted,
520507
borrow_set,
521508
region_inference_context: regioncx,
522509
location_table: polonius_input.as_ref().map(|_| location_table),
523510
input_facts: polonius_input,
524-
output_facts,
511+
output_facts: polonius_output,
525512
}))
526513
} else {
527514
None
@@ -654,13 +641,6 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
654641
location_table: &'a PoloniusLocationTable,
655642

656643
movable_coroutine: bool,
657-
/// This keeps track of whether local variables are free-ed when the function
658-
/// exits even without a `StorageDead`, which appears to be the case for
659-
/// constants.
660-
///
661-
/// I'm not sure this is the right approach - @eddyb could you try and
662-
/// figure this out?
663-
locals_are_invalidated_at_exit: bool,
664644
/// This field keeps track of when borrow errors are reported in the access_place function
665645
/// so that there is no duplicate reporting. This field cannot also be used for the conflicting
666646
/// borrow errors that is handled by the `reservation_error_reported` field as the inclusion
@@ -708,12 +688,11 @@ struct MirBorrowckCtxt<'a, 'infcx, 'tcx> {
708688
/// The counter for generating new region names.
709689
next_region_name: RefCell<usize>,
710690

711-
/// Results of Polonius analysis.
712-
polonius_output: Option<Box<PoloniusOutput>>,
713-
714691
diags_buffer: &'a mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>,
715692
move_errors: Vec<MoveError<'tcx>>,
716693

694+
/// Results of Polonius analysis.
695+
polonius_output: Option<&'a PoloniusOutput>,
717696
/// When using `-Zpolonius=next`: the data used to compute errors and diagnostics.
718697
polonius_diagnostics: Option<&'a PoloniusDiagnosticsContext>,
719698
}
@@ -937,13 +916,20 @@ impl<'a, 'tcx> ResultsVisitor<'a, 'tcx, Borrowck<'a, 'tcx>> for MirBorrowckCtxt<
937916
| TerminatorKind::Return
938917
| TerminatorKind::TailCall { .. }
939918
| TerminatorKind::CoroutineDrop => {
940-
// Returning from the function implicitly kills storage for all locals and statics.
941-
// Often, the storage will already have been killed by an explicit
942-
// StorageDead, but we don't always emit those (notably on unwind paths),
943-
// so this "extra check" serves as a kind of backup.
944-
for i in state.borrows.iter() {
945-
let borrow = &self.borrow_set[i];
946-
self.check_for_invalidation_at_exit(loc, borrow, span);
919+
match self.borrow_set.locals_state_at_exit() {
920+
LocalsStateAtExit::AllAreInvalidated => {
921+
// Returning from the function implicitly kills storage for all locals and statics.
922+
// Often, the storage will already have been killed by an explicit
923+
// StorageDead, but we don't always emit those (notably on unwind paths),
924+
// so this "extra check" serves as a kind of backup.
925+
for i in state.borrows.iter() {
926+
let borrow = &self.borrow_set[i];
927+
self.check_for_invalidation_at_exit(loc, borrow, span);
928+
}
929+
}
930+
// If we do not implicitly invalidate all locals on exit,
931+
// we check for conflicts when dropping or moving this local.
932+
LocalsStateAtExit::SomeAreInvalidated { has_storage_dead_or_moved: _ } => {}
947933
}
948934
}
949935

@@ -1715,22 +1701,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, '_, 'tcx> {
17151701
// we'll have a memory leak) and assume that all statics have a destructor.
17161702
//
17171703
// FIXME: allow thread-locals to borrow other thread locals?
1718-
1719-
let (might_be_alive, will_be_dropped) =
1720-
if self.body.local_decls[root_place.local].is_ref_to_thread_local() {
1721-
// Thread-locals might be dropped after the function exits
1722-
// We have to dereference the outer reference because
1723-
// borrows don't conflict behind shared references.
1724-
root_place.projection = TyCtxtConsts::DEREF_PROJECTION;
1725-
(true, true)
1726-
} else {
1727-
(false, self.locals_are_invalidated_at_exit)
1728-
};
1729-
1730-
if !will_be_dropped {
1731-
debug!("place_is_invalidated_at_exit({:?}) - won't be dropped", place);
1732-
return;
1733-
}
1704+
let might_be_alive = if self.body.local_decls[root_place.local].is_ref_to_thread_local() {
1705+
// Thread-locals might be dropped after the function exits
1706+
// We have to dereference the outer reference because
1707+
// borrows don't conflict behind shared references.
1708+
root_place.projection = TyCtxtConsts::DEREF_PROJECTION;
1709+
true
1710+
} else {
1711+
false
1712+
};
17341713

17351714
let sd = if might_be_alive { Deep } else { Shallow(None) };
17361715

Diff for: compiler/rustc_borrowck/src/nll.rs

+4-17
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use tracing::{debug, instrument};
2121

2222
use crate::borrow_set::BorrowSet;
2323
use crate::consumers::ConsumerOptions;
24-
use crate::diagnostics::{BorrowckDiagnosticsBuffer, RegionErrors};
24+
use crate::diagnostics::RegionErrors;
2525
use crate::polonius::PoloniusDiagnosticsContext;
2626
use crate::polonius::legacy::{
2727
PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput,
@@ -117,11 +117,6 @@ pub(crate) fn compute_regions<'a, 'tcx>(
117117
Rc::clone(&location_map),
118118
);
119119

120-
// Create the region inference context, taking ownership of the
121-
// region inference data that was contained in `infcx`, and the
122-
// base constraints generated by the type-check.
123-
let var_infos = infcx.get_region_var_infos();
124-
125120
// If requested, emit legacy polonius facts.
126121
polonius::legacy::emit_facts(
127122
&mut polonius_facts,
@@ -134,13 +129,8 @@ pub(crate) fn compute_regions<'a, 'tcx>(
134129
&constraints,
135130
);
136131

137-
let mut regioncx = RegionInferenceContext::new(
138-
infcx,
139-
var_infos,
140-
constraints,
141-
universal_region_relations,
142-
location_map,
143-
);
132+
let mut regioncx =
133+
RegionInferenceContext::new(infcx, constraints, universal_region_relations, location_map);
144134

145135
// If requested for `-Zpolonius=next`, convert NLL constraints to localized outlives constraints
146136
// and use them to compute loan liveness.
@@ -297,7 +287,6 @@ pub(super) fn dump_annotation<'tcx, 'infcx>(
297287
body: &Body<'tcx>,
298288
regioncx: &RegionInferenceContext<'tcx>,
299289
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
300-
diagnostics_buffer: &mut BorrowckDiagnosticsBuffer<'infcx, 'tcx>,
301290
) {
302291
let tcx = infcx.tcx;
303292
let base_def_id = tcx.typeck_root_def_id(body.source.def_id());
@@ -335,13 +324,11 @@ pub(super) fn dump_annotation<'tcx, 'infcx>(
335324
} else {
336325
let mut err = infcx.dcx().struct_span_note(def_span, "no external requirements");
337326
regioncx.annotate(tcx, &mut err);
338-
339327
err
340328
};
341329

342330
// FIXME(@lcnr): We currently don't dump the inferred hidden types here.
343-
344-
diagnostics_buffer.buffer_non_error(err);
331+
err.emit();
345332
}
346333

347334
fn for_each_region_constraint<'tcx>(

Diff for: compiler/rustc_borrowck/src/polonius/dump.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ pub(crate) fn dump_polonius_mir<'tcx>(
2424
infcx: &BorrowckInferCtxt<'tcx>,
2525
body: &Body<'tcx>,
2626
regioncx: &RegionInferenceContext<'tcx>,
27+
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
2728
borrow_set: &BorrowSet<'tcx>,
2829
polonius_diagnostics: Option<&PoloniusDiagnosticsContext>,
29-
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
3030
) {
3131
let tcx = infcx.tcx;
3232
if !tcx.sess.opts.unstable_opts.polonius.is_next_enabled() {

0 commit comments

Comments
 (0)