Skip to content

Commit 29d6055

Browse files
committed
Auto merge of #155898 - cjgillot:feed-promoted, r=<try>
Create definitions for promoted constants.
2 parents f53b654 + c891124 commit 29d6055

175 files changed

Lines changed: 2143 additions & 2275 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

compiler/rustc_borrowck/src/consumers.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
33
use rustc_data_structures::fx::FxHashMap;
44
use rustc_hir::def_id::LocalDefId;
5-
use rustc_index::IndexVec;
65
use rustc_middle::bug;
7-
use rustc_middle::mir::{Body, Promoted};
6+
use rustc_middle::mir::Body;
87
use rustc_middle::ty::TyCtxt;
98

109
pub use super::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation};
@@ -85,8 +84,6 @@ pub enum ConsumerOptions {
8584
pub struct BodyWithBorrowckFacts<'tcx> {
8685
/// A mir body that contains region identifiers.
8786
pub body: Body<'tcx>,
88-
/// The mir bodies of promoteds.
89-
pub promoted: IndexVec<Promoted, Body<'tcx>>,
9087
/// The set of borrows occurring in `body` with data about them.
9188
pub borrow_set: BorrowSet<'tcx>,
9289
/// Context generated during borrowck, intended to be passed to

compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
12231223

12241224
fn suggest_using_iter_mut(&self, err: &mut Diag<'_>) {
12251225
let source = self.body.source;
1226-
if let InstanceKind::Item(def_id) = source.instance
1226+
if let InstanceKind::Item(def_id) = source
12271227
&& let Some(Node::Expr(hir::Expr { hir_id, kind, .. })) =
12281228
self.infcx.tcx.hir_get_if_local(def_id)
12291229
&& let ExprKind::Closure(hir::Closure { kind: hir::ClosureKind::Closure, .. }) = kind
@@ -1614,7 +1614,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
16141614
}
16151615

16161616
// Make sure we are inside a closure.
1617-
let InstanceKind::Item(body_def_id) = self.body.source.instance else {
1617+
let InstanceKind::Item(body_def_id) = self.body.source else {
16181618
return false;
16191619
};
16201620
let Some(Node::Expr(hir::Expr { hir_id: body_hir_id, kind, .. })) =

compiler/rustc_borrowck/src/lib.rs

Lines changed: 3 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ use rustc_data_structures::graph::dominators::Dominators;
2828
use rustc_hir as hir;
2929
use rustc_hir::CRATE_HIR_ID;
3030
use rustc_hir::def_id::LocalDefId;
31+
use rustc_index::IndexVec;
3132
use rustc_index::bit_set::MixedBitSet;
32-
use rustc_index::{IndexSlice, IndexVec};
3333
use rustc_infer::infer::outlives::env::RegionBoundPairs;
3434
use rustc_infer::infer::{
3535
InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt,
@@ -289,7 +289,6 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
289289
struct CollectRegionConstraintsResult<'tcx> {
290290
infcx: BorrowckInferCtxt<'tcx>,
291291
body_owned: Body<'tcx>,
292-
promoted: IndexVec<Promoted, Body<'tcx>>,
293292
move_data: MoveData<'tcx>,
294293
borrow_set: BorrowSet<'tcx>,
295294
location_table: PoloniusLocationTable,
@@ -313,9 +312,8 @@ fn borrowck_collect_region_constraints<'tcx>(
313312
) -> CollectRegionConstraintsResult<'tcx> {
314313
let tcx = root_cx.tcx;
315314
let infcx = BorrowckInferCtxt::new(tcx, def, root_cx.root_def_id());
316-
let (input_body, promoted) = tcx.mir_promoted(def);
315+
let (input_body, _) = tcx.mir_promoted(def);
317316
let input_body: &Body<'_> = &input_body.borrow();
318-
let input_promoted: &IndexSlice<_, _> = &promoted.borrow();
319317
if let Some(e) = input_body.tainted_by_errors {
320318
infcx.set_tainted_by_errors(e);
321319
root_cx.set_tainted_by_errors(e);
@@ -326,8 +324,7 @@ fn borrowck_collect_region_constraints<'tcx>(
326324
// be modified (in place) to contain non-lexical lifetimes. It
327325
// will have a lifetime tied to the inference context.
328326
let mut body_owned = input_body.clone();
329-
let mut promoted = input_promoted.to_owned();
330-
let universal_regions = nll::replace_regions_in_mir(&infcx, &mut body_owned, &mut promoted);
327+
let universal_regions = nll::replace_regions_in_mir(&infcx, &mut body_owned);
331328
let body = &body_owned; // no further changes
332329

333330
let location_table = PoloniusLocationTable::new(body);
@@ -356,7 +353,6 @@ fn borrowck_collect_region_constraints<'tcx>(
356353
root_cx,
357354
&infcx,
358355
body,
359-
&promoted,
360356
universal_regions,
361357
&location_table,
362358
&borrow_set,
@@ -368,7 +364,6 @@ fn borrowck_collect_region_constraints<'tcx>(
368364
CollectRegionConstraintsResult {
369365
infcx,
370366
body_owned,
371-
promoted,
372367
move_data,
373368
borrow_set,
374369
location_table,
@@ -392,7 +387,6 @@ fn borrowck_check_region_constraints<'tcx>(
392387
CollectRegionConstraintsResult {
393388
infcx,
394389
body_owned,
395-
promoted,
396390
move_data,
397391
borrow_set,
398392
location_table,
@@ -456,54 +450,6 @@ fn borrowck_check_region_constraints<'tcx>(
456450
&& tcx.coroutine_movability(def.to_def_id()) == hir::Movability::Movable;
457451

458452
let diags_buffer = &mut BorrowckDiagnosticsBuffer::default();
459-
// While promoteds should mostly be correct by construction, we need to check them for
460-
// invalid moves to detect moving out of arrays:`struct S; fn main() { &([S][0]); }`.
461-
for promoted_body in &promoted {
462-
use rustc_middle::mir::visit::Visitor;
463-
// This assumes that we won't use some of the fields of the `promoted_mbcx`
464-
// when detecting and reporting move errors. While it would be nice to move
465-
// this check out of `MirBorrowckCtxt`, actually doing so is far from trivial.
466-
let move_data = MoveData::gather_moves(promoted_body, tcx, |_| true);
467-
let mut promoted_mbcx = MirBorrowckCtxt {
468-
root_cx,
469-
infcx: &infcx,
470-
body: promoted_body,
471-
move_data: &move_data,
472-
// no need to create a real location table for the promoted, it is not used
473-
location_table: &location_table,
474-
movable_coroutine,
475-
fn_self_span_reported: Default::default(),
476-
access_place_error_reported: Default::default(),
477-
reservation_error_reported: Default::default(),
478-
uninitialized_error_reported: Default::default(),
479-
regioncx: &regioncx,
480-
used_mut: Default::default(),
481-
used_mut_upvars: SmallVec::new(),
482-
borrow_set: &borrow_set,
483-
upvars: &[],
484-
local_names: OnceCell::from(IndexVec::from_elem(None, &promoted_body.local_decls)),
485-
region_names: RefCell::default(),
486-
next_region_name: RefCell::new(1),
487-
polonius_output: None,
488-
move_errors: Vec::new(),
489-
diags_buffer,
490-
polonius_context: polonius_context.as_ref(),
491-
};
492-
struct MoveVisitor<'a, 'b, 'infcx, 'tcx> {
493-
ctxt: &'a mut MirBorrowckCtxt<'b, 'infcx, 'tcx>,
494-
}
495-
496-
impl<'tcx> Visitor<'tcx> for MoveVisitor<'_, '_, '_, 'tcx> {
497-
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
498-
if let Operand::Move(place) = operand {
499-
self.ctxt.check_movable_place(location, *place);
500-
}
501-
}
502-
}
503-
MoveVisitor { ctxt: &mut promoted_mbcx }.visit_body(promoted_body);
504-
promoted_mbcx.report_move_errors();
505-
}
506-
507453
let mut mbcx = MirBorrowckCtxt {
508454
root_cx,
509455
infcx: &infcx,
@@ -580,7 +526,6 @@ fn borrowck_check_region_constraints<'tcx>(
580526
def,
581527
BodyWithBorrowckFacts {
582528
body: body_owned,
583-
promoted,
584529
borrow_set,
585530
region_inference_context: regioncx,
586531
location_table: polonius_input.as_ref().map(|_| location_table),

compiler/rustc_borrowck/src/nll.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ use std::str::FromStr;
88
use polonius_engine::{Algorithm, AllFacts, Output};
99
use rustc_data_structures::frozen::Frozen;
1010
use rustc_hir::find_attr;
11-
use rustc_index::IndexSlice;
1211
use rustc_middle::mir::pretty::PrettyPrintMirOptions;
13-
use rustc_middle::mir::{Body, MirDumper, PassWhere, Promoted};
12+
use rustc_middle::mir::{Body, MirDumper, PassWhere};
1413
use rustc_middle::ty::print::with_no_trimmed_paths;
1514
use rustc_middle::ty::{self, TyCtxt};
1615
use rustc_mir_dataflow::move_paths::MoveData;
@@ -52,11 +51,10 @@ pub(crate) struct NllOutput<'tcx> {
5251
/// Rewrites the regions in the MIR to use NLL variables, also scraping out the set of universal
5352
/// regions (e.g., region parameters) declared on the function. That set will need to be given to
5453
/// `compute_regions`.
55-
#[instrument(skip(infcx, body, promoted), level = "debug")]
54+
#[instrument(skip(infcx, body), level = "debug")]
5655
pub(crate) fn replace_regions_in_mir<'tcx>(
5756
infcx: &BorrowckInferCtxt<'tcx>,
5857
body: &mut Body<'tcx>,
59-
promoted: &mut IndexSlice<Promoted, Body<'tcx>>,
6058
) -> UniversalRegions<'tcx> {
6159
let def = body.source.def_id().expect_local();
6260

@@ -66,7 +64,7 @@ pub(crate) fn replace_regions_in_mir<'tcx>(
6664
let universal_regions = UniversalRegions::new(infcx, def);
6765

6866
// Replace all remaining regions with fresh inference variables.
69-
renumber::renumber_mir(infcx, body, promoted);
67+
renumber::renumber_mir(infcx, body);
7068

7169
if let Some(dumper) = MirDumper::new(infcx.tcx, "renumber", body) {
7270
dumper.dump_mir(body);

compiler/rustc_borrowck/src/region_infer/values.rs

Lines changed: 11 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::fmt::Debug;
22
use std::rc::Rc;
33

4-
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
4+
use rustc_data_structures::fx::FxIndexSet;
55
use rustc_index::Idx;
66
use rustc_index::bit_set::SparseBitMatrix;
77
use rustc_index::interval::{IntervalSet, SparseIntervalMatrix};
@@ -42,15 +42,11 @@ pub(crate) struct LivenessValues {
4242
/// The map from locations to points.
4343
location_map: Rc<DenseLocationMap>,
4444

45-
/// Which regions are live. This is exclusive with the fine-grained tracking in `points`, and
46-
/// currently only used for validating promoteds (which don't care about more precise tracking).
47-
live_regions: Option<FxHashSet<RegionVid>>,
48-
4945
/// For each region: the points where it is live.
5046
///
5147
/// This is not initialized for promoteds, because we don't care *where* within a promoted a
5248
/// region is live, only that it is.
53-
points: Option<SparseIntervalMatrix<RegionVid, PointIndex>>,
49+
points: SparseIntervalMatrix<RegionVid, PointIndex>,
5450

5551
/// When using `-Zpolonius=next`, the set of loans that are live at a given point in the CFG.
5652
live_loans: Option<LiveLoans>,
@@ -60,21 +56,7 @@ impl LivenessValues {
6056
/// Create an empty map of regions to locations where they're live.
6157
pub(crate) fn with_specific_points(location_map: Rc<DenseLocationMap>) -> Self {
6258
LivenessValues {
63-
live_regions: None,
64-
points: Some(SparseIntervalMatrix::new(location_map.num_points())),
65-
location_map,
66-
live_loans: None,
67-
}
68-
}
69-
70-
/// Create an empty map of regions to locations where they're live.
71-
///
72-
/// Unlike `with_specific_points`, does not track exact locations where something is live, only
73-
/// which regions are live.
74-
pub(crate) fn without_specific_points(location_map: Rc<DenseLocationMap>) -> Self {
75-
LivenessValues {
76-
live_regions: Some(Default::default()),
77-
points: None,
59+
points: SparseIntervalMatrix::new(location_map.num_points()),
7860
location_map,
7961
live_loans: None,
8062
}
@@ -83,52 +65,30 @@ impl LivenessValues {
8365
/// Returns the liveness matrix of points where each region is live. Panics if the liveness
8466
/// values have been created without any per-point data (that is, for promoteds).
8567
pub(crate) fn points(&self) -> &SparseIntervalMatrix<RegionVid, PointIndex> {
86-
self.points
87-
.as_ref()
88-
.expect("this `LivenessValues` wasn't created using `with_specific_points`")
68+
&self.points
8969
}
9070

9171
/// Iterate through each region that has a value in this set.
9272
pub(crate) fn regions(&self) -> impl Iterator<Item = RegionVid> {
93-
self.points.as_ref().expect("use with_specific_points").rows()
94-
}
95-
96-
/// Iterate through each region that has a value in this set.
97-
// We are passing query instability implications to the caller.
98-
#[rustc_lint_query_instability]
99-
#[allow(rustc::potential_query_instability)]
100-
pub(crate) fn live_regions_unordered(&self) -> impl Iterator<Item = RegionVid> {
101-
self.live_regions.as_ref().unwrap().iter().copied()
73+
self.points.rows()
10274
}
10375

10476
/// Records `region` as being live at the given `location`.
10577
pub(crate) fn add_location(&mut self, region: RegionVid, location: Location) {
10678
let point = self.location_map.point_from_location(location);
10779
debug!("LivenessValues::add_location(region={:?}, location={:?})", region, location);
108-
if let Some(points) = &mut self.points {
109-
points.insert(region, point);
110-
} else if self.location_map.point_in_range(point) {
111-
self.live_regions.as_mut().unwrap().insert(region);
112-
}
80+
self.points.insert(region, point);
11381
}
11482

11583
/// Records `region` as being live at all the given `points`.
11684
pub(crate) fn add_points(&mut self, region: RegionVid, points: &IntervalSet<PointIndex>) {
11785
debug!("LivenessValues::add_points(region={:?}, points={:?})", region, points);
118-
if let Some(this) = &mut self.points {
119-
this.union_row(region, points);
120-
} else if points.iter().any(|point| self.location_map.point_in_range(point)) {
121-
self.live_regions.as_mut().unwrap().insert(region);
122-
}
86+
self.points.union_row(region, points);
12387
}
12488

12589
/// Records `region` as being live at all the control-flow points.
12690
pub(crate) fn add_all_points(&mut self, region: RegionVid) {
127-
if let Some(points) = &mut self.points {
128-
points.insert_all_into_row(region);
129-
} else {
130-
self.live_regions.as_mut().unwrap().insert(region);
131-
}
91+
self.points.insert_all_into_row(region);
13292
}
13393

13494
/// Returns whether `region` is marked live at the given
@@ -142,23 +102,12 @@ impl LivenessValues {
142102
/// [`point`][rustc_mir_dataflow::points::PointIndex].
143103
#[inline]
144104
pub(crate) fn is_live_at_point(&self, region: RegionVid, point: PointIndex) -> bool {
145-
if let Some(points) = &self.points {
146-
points.row(region).is_some_and(|r| r.contains(point))
147-
} else {
148-
unreachable!(
149-
"Should be using LivenessValues::with_specific_points to ask whether live at a location"
150-
)
151-
}
105+
self.points.row(region).is_some_and(|r| r.contains(point))
152106
}
153107

154108
/// Returns an iterator of all the points where `region` is live.
155109
fn live_points(&self, region: RegionVid) -> impl Iterator<Item = PointIndex> {
156-
let Some(points) = &self.points else {
157-
unreachable!(
158-
"Should be using LivenessValues::with_specific_points to ask whether live at a location"
159-
)
160-
};
161-
points
110+
self.points
162111
.row(region)
163112
.into_iter()
164113
.flat_map(|set| set.iter())
@@ -328,10 +277,7 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> {
328277
/// elements for the region `from` from `values` and add them to
329278
/// the region `to` in `self`.
330279
pub(crate) fn merge_liveness(&mut self, to: N, from: RegionVid, values: &LivenessValues) {
331-
let Some(value_points) = &values.points else {
332-
panic!("LivenessValues must track specific points for use in merge_liveness");
333-
};
334-
if let Some(set) = value_points.row(from) {
280+
if let Some(set) = values.points.row(from) {
335281
self.points.union_row(to, set);
336282
}
337283
}

compiler/rustc_borrowck/src/renumber.rs

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
use rustc_index::IndexSlice;
21
use rustc_infer::infer::NllRegionVariableOrigin;
32
use rustc_middle::mir::visit::{MutVisitor, TyContext};
4-
use rustc_middle::mir::{Body, ConstOperand, Location, Promoted};
3+
use rustc_middle::mir::{Body, ConstOperand, Location};
54
use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypeFoldable, fold_regions};
65
use rustc_span::Symbol;
76
use tracing::{debug, instrument};
@@ -10,21 +9,10 @@ use crate::BorrowckInferCtxt;
109

1110
/// Replaces all free regions appearing in the MIR with fresh
1211
/// inference variables, returning the number of variables created.
13-
#[instrument(skip(infcx, body, promoted), level = "debug")]
14-
pub(crate) fn renumber_mir<'tcx>(
15-
infcx: &BorrowckInferCtxt<'tcx>,
16-
body: &mut Body<'tcx>,
17-
promoted: &mut IndexSlice<Promoted, Body<'tcx>>,
18-
) {
12+
#[instrument(skip(infcx, body), level = "debug")]
13+
pub(crate) fn renumber_mir<'tcx>(infcx: &BorrowckInferCtxt<'tcx>, body: &mut Body<'tcx>) {
1914
debug!(?body.arg_count);
20-
21-
let mut renumberer = RegionRenumberer { infcx };
22-
23-
for body in promoted.iter_mut() {
24-
renumberer.visit_body_preserves_cfg(body);
25-
}
26-
27-
renumberer.visit_body_preserves_cfg(body);
15+
RegionRenumberer { infcx }.visit_body_preserves_cfg(body);
2816
}
2917

3018
// The fields are used only for debugging output in `sccs_info`.

compiler/rustc_borrowck/src/root_cx.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,14 @@ impl<'tcx> BorrowCheckRootCtxt<'tcx> {
266266
.iter()
267267
.chain(std::iter::once(self.root_def_id));
268268
for def_id in all_bodies {
269+
// The list of promoted from a given body is a flat list,
270+
// in topological order from innermost to outermost.
271+
let promoted = self.tcx.promoted_mir(def_id);
272+
for &promoted_def_id in promoted {
273+
let result = borrowck_collect_region_constraints(self, promoted_def_id);
274+
self.collect_region_constraints_results.insert(promoted_def_id, result);
275+
}
276+
269277
let result = borrowck_collect_region_constraints(self, def_id);
270278
self.collect_region_constraints_results.insert(def_id, result);
271279
}

0 commit comments

Comments
 (0)