Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
0defa2c
Stabilize `mem::conjure_zst`
theemathas Aug 25, 2026
66f69fc
No longer auto-inline `f16` and `f128` on well-supported platforms
tgross35 Sep 17, 2026
b84b0bb
Add rustdoc regression test for glob import of a crate that re-export…
zakrad Sep 21, 2026
93bfeed
Add regression tests for Option predicate suggestion precedence
chenyukang Sep 21, 2026
c9412ec
Fix suggestion for Option to bool with proper precedence handling
chenyukang Sep 23, 2026
e01dc94
Some `emit_diagnostic` improvements
nnethercote Sep 17, 2026
4fc112e
Remove an out-of-date FIXME comment
nnethercote Sep 22, 2026
e10ba5d
Add test for issue 163293
mu001999 Sep 25, 2026
b10ccb8
Don't emit sugg for pub-reexport extern std
mu001999 Sep 25, 2026
5237e38
Support -Z merge-functions with gcc and add stack-protector asm tests
Sep 24, 2026
c6dc511
address comments by bjorn3
Sep 24, 2026
d744bc3
remove the location map Rc
lqd Sep 24, 2026
c9bcd7a
more comment
lqd Sep 24, 2026
e34a4bc
rename `DeferredLocals` to `DeferredRegionLiveness`
lqd Sep 24, 2026
c0d719b
use the now available name `deferred_locals`
lqd Sep 24, 2026
a17bea3
collapse interesting construct
lqd Sep 24, 2026
63b6563
micro-optimize gathering polonius-relevant locals
lqd Sep 24, 2026
bf6b17e
slight cleanups in `DeferredRegionLiveness`
lqd Sep 24, 2026
b835ee0
cleanup in `dropck_boring_local`
lqd Sep 24, 2026
21c6277
Fix invalid jump to def link when `#[rustc_allow_incoherent_impl]` is…
GuillaumeGomez Sep 21, 2026
3e574ad
Add some docs to `Global`
maxdexh Sep 25, 2026
d29d905
use `inner` for the `RegionInferenceContextInner` fields
lqd Sep 25, 2026
dd39de7
reduce field visibility
lqd Sep 25, 2026
14cd34f
move functions that panic on the unsolved regioncx
lqd Sep 25, 2026
005e444
make unique entry point to regioncx creation
lqd Sep 25, 2026
29c3e37
update comment and visibility
lqd Sep 25, 2026
49276b0
Detect bad number of generics caused by bad derive
estebank Aug 6, 2026
fcf74ea
Merge `ForceWarning`/`Allow`/`Expect` into `Warning`
nnethercote Sep 22, 2026
1d910ae
simplify ndk compiler test
malezjaa Sep 25, 2026
06568dc
Rollup merge of #160695 - estebank:issue-160463, r=petrochenkov
jhpratt Sep 26, 2026
f28dc24
Rollup merge of #162883 - tgross35:f16-f128-autoinline, r=saethlin
jhpratt Sep 26, 2026
061c90a
Rollup merge of #163133 - GuillaumeGomez:jump-to-def-incoherent, r=Urgau
jhpratt Sep 26, 2026
a771f75
Rollup merge of #163215 - chenyukang:yukang-fix-option-to-bool-sugges…
jhpratt Sep 26, 2026
7fff16f
Rollup merge of #163266 - lqd:deferred-liveness2-electric-boogaloo, r…
jhpratt Sep 26, 2026
727dc4a
Rollup merge of #163274 - arielb1:stack-protector-tests-gcc, r=Guilla…
jhpratt Sep 26, 2026
7756b3e
Rollup merge of #163290 - nnethercote:merge-warning-levels, r=oli-obk
jhpratt Sep 26, 2026
e3e8097
Rollup merge of #163298 - mu001999-contrib:fix-163293, r=saethlin
jhpratt Sep 26, 2026
2a7ef61
Rollup merge of #163312 - zakrad:regr-test-53724, r=notriddle
jhpratt Sep 26, 2026
303b5a7
Rollup merge of #163357 - lqd:deferred-liveness-tokyo-drift, r=jackh726
jhpratt Sep 26, 2026
a984b9c
Rollup merge of #161710 - theemathas:stab-conjure-zst, r=clarfonthey
jhpratt Sep 26, 2026
aa101fd
Rollup merge of #163332 - maxdexh:global-allocator-docs, r=clarfonthey
jhpratt Sep 26, 2026
84d685f
Rollup merge of #163362 - malezjaa:simplify-ndk-compiler-test, r=jiey…
jhpratt Sep 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions compiler/rustc_borrowck/src/nll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::polonius::PoloniusContext;
use crate::polonius::legacy::{
PoloniusFacts, PoloniusFactsExt, PoloniusLocationTable, PoloniusOutput,
};
use crate::region_infer::{RegionInferenceContext, UnsolvedRegionInferenceContext};
use crate::region_infer::RegionInferenceContext;
use crate::type_check::MirTypeckRegionConstraints;
use crate::type_check::free_region_relations::UniversalRegionRelations;
use crate::universal_regions::UniversalRegions;
Expand Down Expand Up @@ -96,14 +96,15 @@ pub(crate) fn compute_closure_requirements_modulo_opaques<'tcx>(
&universal_region_relations,
infcx,
);
let regioncx = UnsolvedRegionInferenceContext::new(
let (_, closure_region_requirements, _nll_errors) = RegionInferenceContext::solve(
&infcx,
lowered_constraints,
universal_region_relations.clone(),
location_map,
body,
None,
);

let (_, closure_region_requirements, _nll_errors) = regioncx.solve(infcx, body, None);
closure_region_requirements
}

Expand Down Expand Up @@ -156,7 +157,7 @@ pub(crate) fn compute_regions<'tcx>(
&universal_region_relations.universal_regions,
body,
move_data,
Rc::clone(&location_map),
&location_map,
borrow_set,
);
}
Expand All @@ -182,17 +183,16 @@ pub(crate) fn compute_regions<'tcx>(
}
});

let regioncx = UnsolvedRegionInferenceContext::new(
// Solve the region constraints.
let (regioncx, closure_region_requirements, nll_errors) = RegionInferenceContext::solve(
infcx,
lowered_constraints,
universal_region_relations,
location_map,
body,
polonius_output.clone(),
);

// Solve the region constraints.
let (regioncx, closure_region_requirements, nll_errors) =
regioncx.solve(infcx, body, polonius_output.clone());

NllOutput {
regioncx,
polonius_input: polonius_facts.map(Box::new),
Expand Down
17 changes: 7 additions & 10 deletions compiler/rustc_borrowck/src/polonius/constraints.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
use std::rc::Rc;

use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_index::IndexVec;
use rustc_middle::mir::{Body, Location};
Expand Down Expand Up @@ -41,8 +39,6 @@ pub(super) struct LocalizedNode {
/// The localized constraint graph indexes the physical and logical edges to lazily compute a given
/// node's successors during traversal.
pub(super) struct LocalizedConstraintGraph {
location_map: Rc<DenseLocationMap>,

/// The actual, physical, edges we have recorded for a given node. We localize them on-demand
/// when traversing from the node to the successor region.
edges: FxHashMap<LocalizedNode, SmallVec<[RegionVid; 4]>>,
Expand All @@ -67,7 +63,7 @@ pub(super) trait LocalizedConstraintGraphVisitor {
impl LocalizedConstraintGraph {
/// Traverses the constraints and returns the indexed graph of edges per node.
pub(super) fn new<'tcx>(
location_map: Rc<DenseLocationMap>,
location_map: &DenseLocationMap,
outlives_constraints: impl Iterator<Item = OutlivesConstraint<'tcx>>,
) -> Self {
let mut edges: FxHashMap<_, SmallVec<[RegionVid; 4]>> = FxHashMap::default();
Expand Down Expand Up @@ -96,7 +92,7 @@ impl LocalizedConstraintGraph {
}
}

LocalizedConstraintGraph { location_map, edges, logical_edges }
LocalizedConstraintGraph { edges, logical_edges }
}

/// Traverses the localized constraint graph per-loan, and notifies the `visitor` of discovered
Expand All @@ -105,6 +101,7 @@ impl LocalizedConstraintGraph {
&self,
body: &Body<'tcx>,
borrow_set: &BorrowSet<'tcx>,
location_map: &DenseLocationMap,
liveness_source: &mut impl LivenessSource,
visitor: &mut impl LocalizedConstraintGraphVisitor,
) {
Expand All @@ -119,15 +116,15 @@ impl LocalizedConstraintGraph {

let start_node = LocalizedNode {
region: loan.region,
point: self.location_map.point_from_location(loan.reserve_location),
point: location_map.point_from_location(loan.reserve_location),
};
visited.insert(start_node);
stack.push(start_node);

while let Some(node) = stack.pop() {
let liveness = liveness_source.liveness_for_region(node.region);
// We've reached a node we haven't visited before.
let location = self.location_map.to_location(node.point);
let location = location_map.to_location(node.point);
visitor.on_node_traversed(loan_idx, node, liveness.is_live_at(node.point));

// When we find a _new_ successor, we'd like to
Expand Down Expand Up @@ -183,7 +180,7 @@ impl LocalizedConstraintGraph {
for successor_block in body[location.block].terminator().successors() {
let next_location =
Location { block: successor_block, statement_index: 0 };
let next_point = self.location_map.point_from_location(next_location);
let next_point = location_map.point_from_location(next_location);
if liveness.is_live_at(next_point) {
successor_found(LocalizedNode {
region: node.region,
Expand Down Expand Up @@ -226,7 +223,7 @@ impl LocalizedConstraintGraph {
statement_index: body[pred_block].statements.len(),
};
let previous_point =
self.location_map.point_from_location(previous_location);
location_map.point_from_location(previous_location);
successor_found(LocalizedNode {
region: node.region,
point: previous_point,
Expand Down
20 changes: 11 additions & 9 deletions compiler/rustc_borrowck/src/polonius/dump.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use rustc_index::IndexVec;
use rustc_middle::mir::pretty::{MirDumper, PassWhere, PrettyPrintMirOptions};
use rustc_middle::mir::{Body, Location};
use rustc_middle::ty::{RegionVid, TyCtxt};
use rustc_mir_dataflow::points::PointIndex;
use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex};
use rustc_session::config::MirIncludeSpans;

use crate::borrow_set::BorrowSet;
Expand Down Expand Up @@ -71,7 +71,8 @@ pub(crate) fn dump_polonius_mir<'tcx>(
};
let mut collector = MirDumpCollector::default();
if let Some(graph) = &polonius_context.graph {
graph.traverse(body, borrow_set, &mut liveness_source, &mut collector);
let location_map = regioncx.liveness_constraints().location_map();
graph.traverse(body, borrow_set, location_map, &mut liveness_source, &mut collector);
}

let extra_data = &|pass_where, out: &mut dyn io::Write| {
Expand Down Expand Up @@ -172,7 +173,7 @@ fn emit_polonius_dump<'tcx>(
"POLONIUS_CONSTRAINTS" => {
edge_count = emit_mermaid_constraint_graph(
borrow_set,
regioncx.liveness_constraints(),
regioncx.liveness_constraints().location_map(),
&collector.constraints,
out,
)?;
Expand Down Expand Up @@ -271,7 +272,7 @@ fn emit_polonius_mir<'tcx>(
out,
)?;

let liveness = regioncx.liveness_constraints();
let location_map = regioncx.liveness_constraints().location_map();

// Add localized outlives constraints
match pass_where {
Expand All @@ -281,8 +282,8 @@ fn emit_polonius_mir<'tcx>(

for constraint in localized_outlives_constraints {
let LocalizedOutlivesConstraint { source, from, target, to } = constraint;
let from = liveness.location_from_point(*from);
let to = liveness.location_from_point(*to);
let from = location_map.to_location(*from);
let to = location_map.to_location(*to);
writeln!(out, "| {source:?} at {from:?} -> {target:?} at {to:?}")?;
}
writeln!(out, "|")?;
Expand Down Expand Up @@ -462,12 +463,12 @@ fn emit_mermaid_nll_sccs<'tcx>(
/// region, and loan introductions.
fn emit_mermaid_constraint_graph<'tcx>(
borrow_set: &BorrowSet<'tcx>,
liveness: &LivenessValues,
location_map: &DenseLocationMap,
localized_outlives_constraints: &[LocalizedOutlivesConstraint],
out: &mut dyn io::Write,
) -> io::Result<usize> {
let node_label = |region: RegionVid, point: PointIndex| {
let location = liveness.location_from_point(point);
let location = location_map.to_location(point);
node_name(region, location)
};

Expand Down Expand Up @@ -533,6 +534,7 @@ fn emit_loan_reachability(
reachability: &FxIndexMap<BorrowIndex, Vec<LocalizedNode>>,
out: &mut dyn io::Write,
) -> io::Result<()> {
let location_map = liveness.location_map();
for (loan, _) in borrow_set.iter_enumerated() {
let Some(reachability) = reachability.get(&loan) else {
continue;
Expand All @@ -553,7 +555,7 @@ fn emit_loan_reachability(
for (idx, node) in reachability.iter().enumerate() {
writeln!(out, "<li>")?;

let location = liveness.location_from_point(node.point);
let location = location_map.to_location(node.point);
let kind = if idx == 0 { "starts in" } else { "reaches" };
writeln!(
out,
Expand Down
15 changes: 9 additions & 6 deletions compiler/rustc_borrowck/src/polonius/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ impl<'a> RegionLiveness<'a> {
}

/// The data needed to compute region liveness on-demand while traversing the localized outlives
/// constraint graph to compute loan liveness.
/// constraint graph to compute loan liveness. Each region comes from a local's type, so this holds
/// mostly the locals and drop-liveness specifics about their type, to be used as inputs to the
/// `LivenessComputation` giving us the region liveness.
#[derive(Default)]
pub(crate) struct DeferredLocals<'tcx> {
pub(crate) struct DeferredRegionLiveness<'tcx> {
/// For each region, the local whose liveness is deferred.
///
/// Importantly, because of MIR renumbering, this will always be a 1:1 relationship.
Expand All @@ -69,7 +71,9 @@ pub(crate) struct DeferredLocals<'tcx> {
drop_args_by_local: IndexVec<Local, Option<Vec<GenericArg<'tcx>>>>,
}

impl<'tcx> DeferredLocals<'tcx> {
impl<'tcx> DeferredRegionLiveness<'tcx> {
/// We want to defer computing the liveness of the region in the local's type, so we store the
/// necessary inputs to do that later.
pub(crate) fn defer_local(
&mut self,
tcx: TyCtxt<'tcx>,
Expand All @@ -86,7 +90,6 @@ impl<'tcx> DeferredLocals<'tcx> {
// Then, we want to map all the regions contained within this local to
// the local itself. Later, when asked for liveness of a given region,
// we can trace liveness for the local containing it.
let by_region = &mut self.by_region;
tcx.for_each_free_region(&local_ty, |region| {
// See note in `VarianceExtractor::record_variance`.
if region.is_bound() || region.is_erased() {
Expand All @@ -95,7 +98,7 @@ impl<'tcx> DeferredLocals<'tcx> {
let vid = universal_regions.to_region_vid(region);
// Because of MIR renumbering, we should always have a 1:1 mapping
// between a region and a local.
let previous = by_region.insert(vid, local);
let previous = self.by_region.insert(vid, local);
debug_assert!(
previous.is_none(),
"{vid:?} is in the type of both {previous:?} and {local:?}, but \
Expand All @@ -106,7 +109,7 @@ impl<'tcx> DeferredLocals<'tcx> {

/// For a given region, compute the liveness for the local containing it, if it is deferred.
#[inline]
pub(crate) fn compute_deferred_local(
pub(crate) fn ensure_deferred_liveness(
&mut self,
region: RegionVid,
universal_regions: &UniversalRegions<'tcx>,
Expand Down
24 changes: 10 additions & 14 deletions compiler/rustc_borrowck/src/polonius/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ pub(crate) mod legacy;
mod liveness;
mod liveness_constraints;

use std::rc::Rc;

use rustc_data_structures::fx::FxHashSet;
use rustc_index::IndexVec;
use rustc_index::bit_set::DenseBitSet;
Expand All @@ -54,7 +52,7 @@ pub(crate) use self::dump::dump_polonius_mir;
pub(crate) use self::liveness_constraints::record_live_region_variance;
use crate::constraints::OutlivesConstraint;
use crate::dataflow::BorrowIndex;
pub(crate) use crate::polonius::liveness::DeferredLocals;
pub(crate) use crate::polonius::liveness::DeferredRegionLiveness;
use crate::polonius::liveness::{LivenessSource, RegionLiveness};
use crate::region_infer::values::LivenessValues;
use crate::type_check::liveness::{LivenessComputation, LocalUseMap};
Expand Down Expand Up @@ -105,7 +103,7 @@ pub(crate) struct PoloniusContext<'tcx> {
/// diagnostics, to focus on the locals we consider relevant and match NLL diagnostics.
pub(crate) boring_nll_locals: FxHashSet<Local>,

pub(crate) deferred_locals_for_liveness: DeferredLocals<'tcx>,
pub(crate) deferred_liveness: DeferredRegionLiveness<'tcx>,

pub(crate) local_use_map: Option<LocalUseMap>,
}
Expand Down Expand Up @@ -143,7 +141,7 @@ impl<'tcx> PoloniusContext<'tcx> {
universal_regions: &UniversalRegions<'tcx>,
body: &Body<'tcx>,
move_data: &MoveData<'tcx>,
location_map: Rc<DenseLocationMap>,
location_map: &DenseLocationMap,
borrow_set: &BorrowSet<'tcx>,
) {
// We don't need to prepare the graph (index NLL constraints, etc.) if we have no loans to
Expand All @@ -152,27 +150,25 @@ impl<'tcx> PoloniusContext<'tcx> {
// From the outlives constraints, liveness, and variances, we can compute reachability
// on the lazy localized constraint graph to trace the liveness of loans, for the next
// step in the chain (the NLL loan scope and active loans computations).
let graph =
LocalizedConstraintGraph::new(Rc::clone(&location_map), outlives_constraints);
let graph = LocalizedConstraintGraph::new(location_map, outlives_constraints);

let local_use_map = self
.local_use_map
.as_ref()
.expect("local use map should be computed before loan liveness");
let deferred_locals_for_liveness =
std::mem::take(&mut self.deferred_locals_for_liveness);
let deferred_liveness = std::mem::take(&mut self.deferred_liveness);
let mut live_loans = LiveLoans::new(location_map.num_points(), borrow_set.len());
let comp =
LivenessComputation::new(infcx, body, &location_map, move_data, &local_use_map);
LivenessComputation::new(infcx, body, location_map, move_data, &local_use_map);
let mut liveness_source = DeferredLivenessSource {
liveness,
live_region_variances: &mut self.live_region_variances,
universal_regions,
deferred_locals_for_liveness,
deferred_liveness,
comp,
};
let mut visitor = LoanLivenessVisitor { live_loans: &mut live_loans };
graph.traverse(body, borrow_set, &mut liveness_source, &mut visitor);
graph.traverse(body, borrow_set, location_map, &mut liveness_source, &mut visitor);
liveness.record_live_loans(live_loans);

// The graph can be traversed again during MIR dumping, so we store it here.
Expand All @@ -188,14 +184,14 @@ struct DeferredLivenessSource<'a, 'tcx> {
liveness: &'a mut LivenessValues,
live_region_variances: &'a mut LiveRegionVariances,
universal_regions: &'a UniversalRegions<'tcx>,
deferred_locals_for_liveness: DeferredLocals<'tcx>,
deferred_liveness: DeferredRegionLiveness<'tcx>,
comp: LivenessComputation<'a, 'tcx>,
}

impl<'a> LivenessSource for DeferredLivenessSource<'a, '_> {
#[inline]
fn liveness_for_region(&mut self, region: RegionVid) -> RegionLiveness<'_> {
self.deferred_locals_for_liveness.compute_deferred_local(
self.deferred_liveness.ensure_deferred_liveness(
region,
self.universal_regions,
&mut self.liveness,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/region_infer/dump_mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
with_msg: &mut dyn FnMut(&str) -> io::Result<()>,
) -> io::Result<()> {
for region in self.definitions.indices() {
let value = self.liveness_constraints.pretty_print_live_points(region);
let value = self.liveness_constraints().pretty_print_live_points(region);
if value != "{}" {
with_msg(&format!("{region:?} live at {value}"))?;
}
Expand Down
Loading
Loading