Skip to content

Commit 6540795

Browse files
committed
Auto merge of #157828 - JonathanBrouwer:rollup-2tPqsx9, r=JonathanBrouwer
Rollup of 23 pull requests Successful merges: - #144220 (Add powerpc64-unknown-linux-gnuelfv2 target) - #153238 (debuginfo: slices are DW_TAG_array_type's) - #157112 (Update aarch64-unknown-freebsd target description) - #157322 (test pre-stabilization items on CI) - #157348 (Don't track cwd for `-Zremap-cwd-prefix` in incremental compilation) - #157490 (Add field-wise CoerceShared reborrow tests) - #157655 (Make Share::share final and improve docs) - #157672 (Region inference: Simplify initialisation of region values) - #157680 (Require `#[pin_v2]` for explicit pin-projection patterns) - #157688 (Create experimental test job `aarch64-apple-macos-26` for evaluating `macos-26` runner images) - #157796 (rustdoc: Some more lazy formatting) - #157818 (miri subtree update) - #157069 (Test that you can't implement Unpin for a compiler-generated future using TAIT) - #157079 (Don't recover `&raw EXPR` as a missing comma) - #157202 (add #[rustc_no_writable] to slice::get_unchecked_mut) - #157622 (Disable retagging for variadic arguments in const-eval) - #157684 (-Zassumptions-on-binders: insert empty assumptions when entering binders in the solver) - #157695 (Extend capabilities of `TypeFoldable_Generic`) - #157766 (interpret: avoid computing layout of sized raw pointee) - #157785 (fuchsia: Support AddressSanitizer on riscv64gc-unknown-fuchsia) - #157795 (revert 157013) - #157798 (Prevent approving PRs that wait for Crater or formal decisions) - #157803 (Rename `errors.rs` file to `diagnostics.rs` (7/N)) Failed merges: - #157752 (Rename `errors.rs` file to `diagnostics.rs` (6/N))
2 parents 3bdd7f8 + 5e5789c commit 6540795

191 files changed

Lines changed: 3824 additions & 811 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.

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4892,6 +4892,7 @@ dependencies = [
48924892
name = "rustc_type_ir_macros"
48934893
version = "0.0.0"
48944894
dependencies = [
4895+
"indexmap",
48954896
"proc-macro2",
48964897
"quote",
48974898
"syn",

compiler/rustc_borrowck/src/diagnostics/find_use.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl<'a, 'tcx> UseFinder<'a, 'tcx> {
3535

3636
queue.push_back(self.start_point);
3737
while let Some(p) = queue.pop_front() {
38-
if !self.regioncx.region_contains(self.region_vid, p) {
38+
if !self.regioncx.region_contains_point(self.region_vid, p) {
3939
continue;
4040
}
4141

compiler/rustc_borrowck/src/region_infer/mod.rs

Lines changed: 41 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::diagnostics::{RegionErrorKind, RegionErrors, UniverseInfo};
3030
use crate::handle_placeholders::{LoweredConstraints, RegionTracker};
3131
use crate::polonius::LiveLoans;
3232
use crate::polonius::legacy::PoloniusOutput;
33-
use crate::region_infer::values::{LivenessValues, RegionElement, RegionValues, ToElementIndex};
33+
use crate::region_infer::values::{LivenessValues, RegionElement, RegionValues};
3434
use crate::type_check::Locations;
3535
use crate::type_check::free_region_relations::UniversalRegionRelations;
3636
use crate::universal_regions::UniversalRegions;
@@ -345,7 +345,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
345345
outlives_constraints,
346346
scc_annotations,
347347
type_tests,
348-
liveness_constraints,
348+
mut liveness_constraints,
349349
universe_causes,
350350
placeholder_indices,
351351
} = lowered_constraints;
@@ -364,106 +364,54 @@ impl<'tcx> RegionInferenceContext<'tcx> {
364364
let mut scc_values =
365365
RegionValues::new(location_map, universal_regions.len(), placeholder_indices);
366366

367-
for region in liveness_constraints.regions() {
367+
// Initializes the region variables with their initial live points.
368+
for (region, definition) in definitions.iter_enumerated() {
368369
let scc = constraint_sccs.scc(region);
369-
scc_values.merge_liveness(scc, region, &liveness_constraints);
370-
}
371370

372-
let mut result = Self {
373-
definitions,
374-
liveness_constraints,
375-
constraints: outlives_constraints,
376-
constraint_graph,
377-
constraint_sccs,
378-
scc_annotations,
379-
universe_causes,
380-
scc_values,
381-
type_tests,
382-
universal_region_relations,
383-
};
384-
385-
result.init_free_and_bound_regions();
386-
387-
result
388-
}
389-
390-
/// Initializes the region variables for each universally
391-
/// quantified region (lifetime parameter). The first N variables
392-
/// always correspond to the regions appearing in the function
393-
/// signature (both named and anonymous) and where-clauses. This
394-
/// function iterates over those regions and initializes them with
395-
/// minimum values.
396-
///
397-
/// For example:
398-
/// ```ignore (illustrative)
399-
/// fn foo<'a, 'b>( /* ... */ ) where 'a: 'b { /* ... */ }
400-
/// ```
401-
/// would initialize two variables like so:
402-
/// ```ignore (illustrative)
403-
/// R0 = { CFG, R0 } // 'a
404-
/// R1 = { CFG, R0, R1 } // 'b
405-
/// ```
406-
/// Here, R0 represents `'a`, and it contains (a) the entire CFG
407-
/// and (b) any universally quantified regions that it outlives,
408-
/// which in this case is just itself. R1 (`'b`) in contrast also
409-
/// outlives `'a` and hence contains R0 and R1.
410-
///
411-
/// This bit of logic also handles invalid universe relations
412-
/// for higher-kinded types.
413-
///
414-
/// We Walk each SCC `A` and `B` such that `A: B`
415-
/// and ensure that universe(A) can see universe(B).
416-
///
417-
/// This serves to enforce the 'empty/placeholder' hierarchy
418-
/// (described in more detail on `RegionKind`):
419-
///
420-
/// ```ignore (illustrative)
421-
/// static -----+
422-
/// | |
423-
/// empty(U0) placeholder(U1)
424-
/// | /
425-
/// empty(U1)
426-
/// ```
427-
///
428-
/// In particular, imagine we have variables R0 in U0 and R1
429-
/// created in U1, and constraints like this;
430-
///
431-
/// ```ignore (illustrative)
432-
/// R1: !1 // R1 outlives the placeholder in U1
433-
/// R1: R0 // R1 outlives R0
434-
/// ```
435-
///
436-
/// Here, we wish for R1 to be `'static`, because it
437-
/// cannot outlive `placeholder(U1)` and `empty(U0)` any other way.
438-
///
439-
/// Thanks to this loop, what happens is that the `R1: R0`
440-
/// constraint has lowered the universe of `R1` to `U0`, which in turn
441-
/// means that the `R1: !1` constraint here will cause
442-
/// `R1` to become `'static`.
443-
fn init_free_and_bound_regions(&mut self) {
444-
for variable in self.definitions.indices() {
445-
let scc = self.constraint_sccs.scc(variable);
446-
447-
match self.definitions[variable].origin {
371+
// For each universally quantified region (lifetime parameter). The
372+
// first N variables always correspond to the regions appearing in the
373+
// function signature (both named and anonymous) and in where-clauses.
374+
match definition.origin {
375+
// For each free, universally quantified region X:
448376
NllRegionVariableOrigin::FreeRegion => {
449-
// For each free, universally quantified region X:
450-
451377
// Add all nodes in the CFG to liveness constraints
452-
self.liveness_constraints.add_all_points(variable);
453-
self.scc_values.add_all_points(scc);
378+
liveness_constraints.add_all_points(region);
454379

455380
// Add `end(X)` into the set for X.
456-
self.scc_values.add_element(scc, variable);
381+
scc_values.add_free_region(scc, region);
457382
}
458383

459384
NllRegionVariableOrigin::Placeholder(placeholder) => {
460-
self.scc_values.add_element(scc, placeholder);
385+
scc_values.add_placeholder(scc, placeholder);
461386
}
462387

463388
NllRegionVariableOrigin::Existential { .. } => {
464389
// For existential, regions, nothing to do.
465390
}
466391
}
392+
393+
// Initially copy the liveness constraints of any region that
394+
// has them, setting `scc_values[scc(region)] |= liveness_constraints[region]`.
395+
//
396+
// These values will later be propagated during [`Self::propagate_constraints()`].
397+
// The values include any live-at-all-points constraints added above
398+
// for free regions.
399+
if let Some(liveness) = liveness_constraints.point_liveness(region) {
400+
scc_values.merge_liveness(scc, liveness)
401+
}
402+
}
403+
404+
Self {
405+
definitions,
406+
liveness_constraints,
407+
constraints: outlives_constraints,
408+
constraint_graph,
409+
constraint_sccs,
410+
scc_annotations,
411+
universe_causes,
412+
scc_values,
413+
type_tests,
414+
universal_region_relations,
467415
}
468416
}
469417

@@ -495,9 +443,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
495443
/// Returns `true` if the region `r` contains the point `p`.
496444
///
497445
/// Panics if called before `solve()` executes,
498-
pub(crate) fn region_contains(&self, r: RegionVid, p: impl ToElementIndex<'tcx>) -> bool {
446+
pub(crate) fn region_contains_point(&self, r: RegionVid, p: Location) -> bool {
499447
let scc = self.constraint_sccs.scc(r);
500-
self.scc_values.contains(scc, p)
448+
self.scc_values.contains_point(scc, p)
501449
}
502450

503451
/// Returns the lowest statement index in `start..=end` which is not contained by `r`.
@@ -608,7 +556,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
608556
// To propagate constraints, we walk the DAG induced by the
609557
// SCC. For each SCC `A`, we visit its successors and compute
610558
// their values, then we union all those values to get our
611-
// own.
559+
// own. This one-shot approach works because iteration is in
560+
// dependency order. I.e. a chain A: B: C will visit C, B, A.
612561
for scc_a in self.constraint_sccs.all_sccs() {
613562
// Walk each SCC `B` such that `A: B`...
614563
for &scc_b in self.constraint_sccs.successors(scc_a) {
@@ -1643,10 +1592,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
16431592
&self.definitions[r]
16441593
}
16451594

1646-
/// Check if the SCC of `r` contains `upper`.
1595+
/// Check if the SCC of `r` contains `upper`, a free region.
16471596
pub(crate) fn upper_bound_in_region_scc(&self, r: RegionVid, upper: RegionVid) -> bool {
16481597
let r_scc = self.constraint_sccs.scc(r);
1649-
self.scc_values.contains(r_scc, upper)
1598+
self.scc_values.contains_free_region(r_scc, upper)
16501599
}
16511600

16521601
pub(crate) fn universal_regions(&self) -> &UniversalRegions<'tcx> {

compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
7878
let placeholder_indices = Default::default();
7979
let mut scc_values =
8080
RegionValues::new(location_map, universal_regions.len(), placeholder_indices);
81-
for variable in definitions.indices() {
81+
for (variable, definition) in definitions.iter_enumerated() {
8282
let scc = constraint_sccs.scc(variable);
83-
match definitions[variable].origin {
83+
match definition.origin {
8484
NllRegionVariableOrigin::FreeRegion => {
85-
scc_values.add_element(scc, variable);
85+
scc_values.add_free_region(scc, variable);
8686
}
8787
_ => {}
8888
}

compiler/rustc_borrowck/src/region_infer/values.rs

Lines changed: 22 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,10 @@ impl LivenessValues {
9595
}
9696
}
9797

98-
/// Iterate through each region that has a value in this set.
99-
pub(crate) fn regions(&self) -> impl Iterator<Item = RegionVid> {
100-
self.points().rows()
98+
/// Get the liveness status of a region `r`, if any.
99+
/// Panics if liveness data is not tracked for any region.
100+
pub(crate) fn point_liveness(&self, region: RegionVid) -> Option<&IntervalSet<PointIndex>> {
101+
self.points().row(region)
101102
}
102103

103104
/// Iterate through each region that has a value in this set.
@@ -166,13 +167,12 @@ impl LivenessValues {
166167
/// [`point`][rustc_mir_dataflow::points::PointIndex].
167168
#[inline]
168169
pub(crate) fn is_live_at_point(&self, region: RegionVid, point: PointIndex) -> bool {
169-
self.points().row(region).is_some_and(|r| r.contains(point))
170+
self.point_liveness(region).is_some_and(|r| r.contains(point))
170171
}
171172

172173
/// Returns an iterator of all the points where `region` is live.
173174
fn live_points(&self, region: RegionVid) -> impl Iterator<Item = PointIndex> {
174-
self.points()
175-
.row(region)
175+
self.point_liveness(region)
176176
.into_iter()
177177
.flat_map(|set| set.iter())
178178
.take_while(|&p| self.location_map.point_in_range(p))
@@ -296,18 +296,6 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> {
296296
}
297297
}
298298

299-
/// Adds the given element to the value for the given region. Returns whether
300-
/// the element is newly added (i.e., was not already present).
301-
pub(crate) fn add_element(&mut self, r: N, elem: impl ToElementIndex<'tcx>) -> bool {
302-
debug!("add(r={:?}, elem={:?})", r, elem);
303-
elem.add_to_row(self, r)
304-
}
305-
306-
/// Adds all the control-flow points to the values for `r`.
307-
pub(crate) fn add_all_points(&mut self, r: N) {
308-
self.points.insert_all_into_row(r);
309-
}
310-
311299
/// Adds all elements in `r_from` to `r_to` (because e.g., `r_to:
312300
/// r_from`).
313301
pub(crate) fn add_region(&mut self, r_to: N, r_from: N) -> bool {
@@ -316,11 +304,6 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> {
316304
| self.placeholders.union_rows(r_from, r_to)
317305
}
318306

319-
/// Returns `true` if the region `r` contains the given element.
320-
pub(crate) fn contains(&self, r: N, elem: impl ToElementIndex<'tcx>) -> bool {
321-
elem.contained_in_row(self, r)
322-
}
323-
324307
/// Returns the lowest statement index in `start..=end` which is not contained by `r`.
325308
pub(crate) fn first_non_contained_inclusive(
326309
&self,
@@ -337,13 +320,9 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> {
337320
Some(first_unset.index() - block.index())
338321
}
339322

340-
/// `self[to] |= values[from]`, essentially: that is, take all the
341-
/// elements for the region `from` from `values` and add them to
342-
/// the region `to` in `self`.
343-
pub(crate) fn merge_liveness(&mut self, to: N, from: RegionVid, values: &LivenessValues) {
344-
if let Some(set) = values.points().row(from) {
345-
self.points.union_row(to, set);
346-
}
323+
/// Merge a row of liveness into our points.
324+
pub(crate) fn merge_liveness(&mut self, to: N, liveness: &IntervalSet<PointIndex>) {
325+
self.points.union_row(to, liveness);
347326
}
348327

349328
/// Returns `true` if `sup_region` contains all the CFG points that
@@ -405,47 +384,26 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> {
405384
pub(crate) fn region_value_str(&self, r: N) -> String {
406385
pretty_print_region_elements(self.elements_contained_in(r))
407386
}
408-
}
409-
410-
pub(crate) trait ToElementIndex<'tcx>: Debug + Copy {
411-
fn add_to_row<N: Idx>(self, values: &mut RegionValues<'tcx, N>, row: N) -> bool;
412-
413-
fn contained_in_row<N: Idx>(self, values: &RegionValues<'tcx, N>, row: N) -> bool;
414-
}
415-
416-
impl ToElementIndex<'_> for Location {
417-
fn add_to_row<N: Idx>(self, values: &mut RegionValues<'_, N>, row: N) -> bool {
418-
let index = values.location_map.point_from_location(self);
419-
values.points.insert(row, index)
420-
}
421387

422-
fn contained_in_row<N: Idx>(self, values: &RegionValues<'_, N>, row: N) -> bool {
423-
let index = values.location_map.point_from_location(self);
424-
values.points.contains(row, index)
425-
}
426-
}
427-
428-
impl ToElementIndex<'_> for RegionVid {
429-
fn add_to_row<N: Idx>(self, values: &mut RegionValues<'_, N>, row: N) -> bool {
430-
values.free_regions.insert(row, self)
388+
/// Add a the free region with rvid `region` to SCC `scc`
389+
pub(crate) fn add_free_region(&mut self, scc: N, region: RegionVid) {
390+
self.free_regions.insert(scc, region);
431391
}
432392

433-
fn contained_in_row<N: Idx>(self, values: &RegionValues<'_, N>, row: N) -> bool {
434-
values.free_regions.contains(row, self)
393+
pub(crate) fn add_placeholder(&mut self, scc: N, placeholder: ty::PlaceholderRegion<'tcx>) {
394+
let index = self.placeholder_indices.lookup_index(placeholder);
395+
self.placeholders.insert(scc, index);
435396
}
436-
}
437397

438-
impl<'tcx> ToElementIndex<'tcx> for ty::PlaceholderRegion<'tcx> {
439-
fn add_to_row<N: Idx>(self, values: &mut RegionValues<'tcx, N>, row: N) -> bool {
440-
let placeholder: ty::PlaceholderRegion<'tcx> = self.into();
441-
let index = values.placeholder_indices.lookup_index(placeholder);
442-
values.placeholders.insert(row, index)
398+
/// Determine if `scc` contains the CFG point `p`.
399+
pub(crate) fn contains_point(&self, scc: N, p: Location) -> bool {
400+
let index = self.location_map.point_from_location(p);
401+
self.points.contains(scc, index)
443402
}
444403

445-
fn contained_in_row<N: Idx>(self, values: &RegionValues<'tcx, N>, row: N) -> bool {
446-
let placeholder: ty::PlaceholderRegion<'tcx> = self.into();
447-
let index = values.placeholder_indices.lookup_index(placeholder);
448-
values.placeholders.contains(row, index)
404+
/// Determine if `scc` contains the free region `free_region`.
405+
pub(crate) fn contains_free_region(&self, scc: N, free_region: RegionVid) -> bool {
406+
self.free_regions.contains(scc, free_region)
449407
}
450408
}
451409

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,14 @@ pub(crate) unsafe fn create_module<'ll>(
201201
if sess.target.arch == Arch::PowerPC64 {
202202
// LLVM 22 updated the ABI alignment for double on AIX: https://github.com/llvm/llvm-project/pull/144673
203203
target_data_layout = target_data_layout.replace("-f64:32:64", "");
204+
205+
// LLVM 22 fixed the data layout calculation for targets that default to ELFv1
206+
// when the ABI is set to ELFv2. With LLVM 21, the ELFv1 datalayout must be used,
207+
// which will overalign function entries.
208+
// https://github.com/llvm/llvm-project/pull/149725
209+
if sess.target.llvm_target == "powerpc64-unknown-linux-gnu" {
210+
target_data_layout = target_data_layout.replace("-Fn32", "-Fi64");
211+
}
204212
}
205213
if sess.target.arch == Arch::AmdGpu {
206214
// LLVM 22 specified ELF mangling in the amdgpu data layout:

0 commit comments

Comments
 (0)