Skip to content

Commit 8b2cab2

Browse files
committed
Move placeholder handling to a proper preprocessing step
This commit breaks out the logic of placheolder rewriting into its own preprocessing step. It's one of the more boring parts of #130227. The only functional change from this is that the preprocessing step (where extra `r: 'static` constraints are added) is performed upstream of Polonius legacy, finally affecting Polonius. That is mostly a by-product, though.
1 parent b660ab9 commit 8b2cab2

File tree

6 files changed

+414
-299
lines changed

6 files changed

+414
-299
lines changed

compiler/rustc_borrowck/src/constraints/mod.rs

+1-109
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@ use rustc_index::{IndexSlice, IndexVec};
55
use rustc_middle::mir::ConstraintCategory;
66
use rustc_middle::ty::{RegionVid, TyCtxt, VarianceDiagInfo};
77
use rustc_span::Span;
8-
use tracing::{debug, instrument};
8+
use tracing::debug;
99

10-
use crate::region_infer::{AnnotatedSccs, ConstraintSccs, RegionDefinition, SccAnnotations};
1110
use crate::type_check::Locations;
12-
use crate::universal_regions::UniversalRegions;
1311

1412
pub(crate) mod graph;
1513

@@ -53,112 +51,6 @@ impl<'tcx> OutlivesConstraintSet<'tcx> {
5351
) -> &IndexSlice<OutlivesConstraintIndex, OutlivesConstraint<'tcx>> {
5452
&self.outlives
5553
}
56-
57-
/// Computes cycles (SCCs) in the graph of regions. In particular,
58-
/// find all regions R1, R2 such that R1: R2 and R2: R1 and group
59-
/// them into an SCC, and find the relationships between SCCs.
60-
pub(crate) fn compute_sccs(
61-
&self,
62-
static_region: RegionVid,
63-
definitions: &IndexVec<RegionVid, RegionDefinition<'tcx>>,
64-
) -> AnnotatedSccs {
65-
let constraint_graph = self.graph(definitions.len());
66-
let region_graph = &constraint_graph.region_graph(self, static_region);
67-
let mut annotation_visitor = SccAnnotations::new(definitions);
68-
(
69-
ConstraintSccs::new_with_annotation(&region_graph, &mut annotation_visitor),
70-
annotation_visitor.scc_to_annotation,
71-
)
72-
}
73-
74-
/// This method handles Universe errors by rewriting the constraint
75-
/// graph. For each strongly connected component in the constraint
76-
/// graph such that there is a series of constraints
77-
/// A: B: C: ... : X where
78-
/// A's universe is smaller than X's and A is a placeholder,
79-
/// add a constraint that A: 'static. This is a safe upper bound
80-
/// in the face of borrow checker/trait solver limitations that will
81-
/// eventually go away.
82-
///
83-
/// For a more precise definition, see the documentation for
84-
/// [`crate::region_infer::RegionTracker`].
85-
///
86-
/// This edge case used to be handled during constraint propagation
87-
/// by iterating over the strongly connected components in the constraint
88-
/// graph while maintaining a set of bookkeeping mappings similar
89-
/// to what is stored in `RegionTracker` and manually adding 'static as
90-
/// needed.
91-
///
92-
/// It was rewritten as part of the Polonius project with the goal of moving
93-
/// higher-kindedness concerns out of the path of the borrow checker,
94-
/// for two reasons:
95-
///
96-
/// 1. Implementing Polonius is difficult enough without also
97-
/// handling them.
98-
/// 2. The long-term goal is to handle higher-kinded concerns
99-
/// in the trait solver, where they belong. This avoids
100-
/// logic duplication and allows future trait solvers
101-
/// to compute better bounds than for example our
102-
/// "must outlive 'static" here.
103-
///
104-
/// This code is a stop-gap measure in preparation for the future trait solver.
105-
///
106-
/// Every constraint added by this method is an
107-
/// internal `IllegalUniverse` constraint.
108-
#[instrument(skip(self, universal_regions, definitions))]
109-
pub(crate) fn add_outlives_static(
110-
&mut self,
111-
universal_regions: &UniversalRegions<'tcx>,
112-
definitions: &IndexVec<RegionVid, RegionDefinition<'tcx>>,
113-
) -> AnnotatedSccs {
114-
let fr_static = universal_regions.fr_static;
115-
let (sccs, annotations) = self.compute_sccs(fr_static, definitions);
116-
117-
// Changed to `true` if we added any constraints to `self` and need to
118-
// recompute SCCs.
119-
let mut added_constraints = false;
120-
121-
for scc in sccs.all_sccs() {
122-
// No point in adding 'static: 'static!
123-
// This micro-optimisation makes somewhat sense
124-
// because static outlives *everything*.
125-
if scc == sccs.scc(fr_static) {
126-
continue;
127-
}
128-
129-
let annotation = annotations[scc];
130-
131-
// If this SCC participates in a universe violation,
132-
// e.g. if it reaches a region with a universe smaller than
133-
// the largest region reached, add a requirement that it must
134-
// outlive `'static`.
135-
if annotation.has_incompatible_universes() {
136-
// Optimisation opportunity: this will add more constraints than
137-
// needed for correctness, since an SCC upstream of another with
138-
// a universe violation will "infect" its downstream SCCs to also
139-
// outlive static.
140-
added_constraints = true;
141-
let scc_representative_outlives_static = OutlivesConstraint {
142-
sup: annotation.representative,
143-
sub: fr_static,
144-
category: ConstraintCategory::IllegalUniverse,
145-
locations: Locations::All(rustc_span::DUMMY_SP),
146-
span: rustc_span::DUMMY_SP,
147-
variance_info: VarianceDiagInfo::None,
148-
from_closure: false,
149-
};
150-
self.push(scc_representative_outlives_static);
151-
}
152-
}
153-
154-
if added_constraints {
155-
// We changed the constraint set and so must recompute SCCs.
156-
self.compute_sccs(fr_static, definitions)
157-
} else {
158-
// If we didn't add any back-edges; no more work needs doing
159-
(sccs, annotations)
160-
}
161-
}
16254
}
16355

16456
impl<'tcx> Index<OutlivesConstraintIndex> for OutlivesConstraintSet<'tcx> {

0 commit comments

Comments
 (0)