Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 359b62c

Browse files
committed
Preliminary attempt at removing placeholders out of the borrow checker.
This version is maximally naive, and currently unsound.
1 parent a3f76a2 commit 359b62c

File tree

5 files changed

+30
-146
lines changed

5 files changed

+30
-146
lines changed

compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -181,19 +181,7 @@ trait TypeOpInfo<'tcx> {
181181
bound: placeholder.bound,
182182
});
183183

184-
let error_region =
185-
if let RegionElement::PlaceholderRegion(error_placeholder) = error_element {
186-
let adjusted_universe =
187-
error_placeholder.universe.as_u32().checked_sub(base_universe.as_u32());
188-
adjusted_universe.map(|adjusted| {
189-
ty::Region::new_placeholder(tcx, ty::Placeholder {
190-
universe: adjusted.into(),
191-
bound: error_placeholder.bound,
192-
})
193-
})
194-
} else {
195-
None
196-
};
184+
let error_region = None;
197185

198186
debug!(?placeholder_region);
199187

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -205,35 +205,20 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
205205
fn suggest_static_lifetime_for_gat_from_hrtb(
206206
&self,
207207
diag: &mut Diag<'_>,
208-
lower_bound: RegionVid,
208+
_lower_bound: RegionVid,
209209
) {
210210
let mut suggestions = vec![];
211211
let hir = self.infcx.tcx.hir();
212212

213213
// find generic associated types in the given region 'lower_bound'
214-
let gat_id_and_generics = self
215-
.regioncx
216-
.placeholders_contained_in(lower_bound)
217-
.map(|placeholder| {
218-
if let Some(id) = placeholder.bound.kind.get_id()
219-
&& let Some(placeholder_id) = id.as_local()
220-
&& let gat_hir_id = self.infcx.tcx.local_def_id_to_hir_id(placeholder_id)
221-
&& let Some(generics_impl) = self
222-
.infcx
223-
.tcx
224-
.parent_hir_node(self.infcx.tcx.parent_hir_id(gat_hir_id))
225-
.generics()
226-
{
227-
Some((gat_hir_id, generics_impl))
228-
} else {
229-
None
230-
}
231-
})
232-
.collect::<Vec<_>>();
233-
debug!(?gat_id_and_generics);
214+
// FIXME: this should find one of the special-case blamable
215+
// new constraints instead!
216+
//let gat_id_and_generics = vec![];
217+
//debug!(?gat_id_and_generics);
234218

235219
// find higher-ranked trait bounds bounded to the generic associated types
236-
let mut hrtb_bounds = vec![];
220+
let hrtb_bounds = vec![];
221+
/*
237222
gat_id_and_generics.iter().flatten().for_each(|(gat_hir_id, generics)| {
238223
for pred in generics.predicates {
239224
let BoundPredicate(WhereBoundPredicate { bound_generic_params, bounds, .. }) = pred
@@ -252,6 +237,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
252237
}
253238
});
254239
debug!(?hrtb_bounds);
240+
*/
255241

256242
hrtb_bounds.iter().for_each(|bound| {
257243
let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }, _) = bound else {

compiler/rustc_borrowck/src/region_infer/mod.rs

Lines changed: 11 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ impl RegionTracker {
116116
}
117117
}
118118

119+
/// If the representative is a placeholder, return it,
120+
/// otherwise return None.
121+
fn placeholder_representative(&self) -> Option<RegionVid> {
122+
if self.representative_is_placeholder { Some(self.representative) } else { None }
123+
}
124+
119125
/// The smallest-indexed universe reachable from and/or in this SCC.
120126
fn min_universe(self) -> UniverseIndex {
121127
self.min_reachable_universe
@@ -429,8 +435,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
429435
sccs_info(infcx, &constraint_sccs);
430436
}
431437

432-
let mut scc_values =
433-
RegionValues::new(elements, universal_regions.len(), &placeholder_indices);
438+
let mut scc_values = RegionValues::new(elements, universal_regions.len());
434439

435440
for region in liveness_constraints.regions() {
436441
let scc = constraint_sccs.scc(region);
@@ -541,10 +546,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
541546
self.scc_values.add_element(scc, variable);
542547
}
543548

544-
NllRegionVariableOrigin::Placeholder(placeholder) => {
545-
self.scc_values.add_element(scc, placeholder);
549+
NllRegionVariableOrigin::Placeholder { .. } => {
550+
// Placeholders are already handled by rewriting constraints.
546551
}
547-
548552
NllRegionVariableOrigin::Existential { .. } => {
549553
// For existential, regions, nothing to do.
550554
}
@@ -603,14 +607,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
603607
self.scc_values.region_value_str(scc)
604608
}
605609

606-
pub(crate) fn placeholders_contained_in<'a>(
607-
&'a self,
608-
r: RegionVid,
609-
) -> impl Iterator<Item = ty::PlaceholderRegion> + 'a {
610-
let scc = self.constraint_sccs.scc(r);
611-
self.scc_values.placeholders_contained_in(scc)
612-
}
613-
614610
/// Returns access to the value of `r` for debugging purposes.
615611
pub(crate) fn region_universe(&self, r: RegionVid) -> ty::UniverseIndex {
616612
self.scc_universe(self.constraint_sccs.scc(r))
@@ -983,7 +979,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
983979
//
984980
// It doesn't matter *what* universe because the promoted `T` will
985981
// always be in the root universe.
986-
if let Some(p) = self.scc_values.placeholders_contained_in(r_scc).next() {
982+
983+
if let Some(p) = self.constraint_sccs.annotation(r_scc).placeholder_representative() {
987984
debug!("encountered placeholder in higher universe: {:?}, requiring 'static", p);
988985
let static_r = self.universal_regions.fr_static;
989986
propagated_outlives_requirements.push(ClosureOutlivesRequirement {
@@ -1649,14 +1646,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
16491646
for error_element in self.scc_values.elements_contained_in(longer_fr_scc) {
16501647
match error_element {
16511648
RegionElement::Location(_) | RegionElement::RootUniversalRegion(_) => {}
1652-
// If we have some bound universal region `'a`, then the only
1653-
// elements it can contain is itself -- we don't know anything
1654-
// else about it!
1655-
RegionElement::PlaceholderRegion(placeholder1) => {
1656-
if placeholder == placeholder1 {
1657-
continue;
1658-
}
1659-
}
16601649
}
16611650

16621651
errors_buffer.push(RegionErrorKind::BoundUniversalRegionError {
@@ -1923,14 +1912,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
19231912
match *element {
19241913
RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l),
19251914
RegionElement::RootUniversalRegion(r) => r,
1926-
RegionElement::PlaceholderRegion(error_placeholder) => self
1927-
.definitions
1928-
.iter_enumerated()
1929-
.find_map(|(r, definition)| match definition.origin {
1930-
NllRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r),
1931-
_ => None,
1932-
})
1933-
.unwrap(),
19341915
}
19351916
}
19361917

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -213,14 +213,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
213213

214214
// Special handling of higher-ranked regions.
215215
if !self.scc_universe(scc).is_root() {
216-
match self.scc_values.placeholders_contained_in(scc).enumerate().last() {
217-
// If the region contains a single placeholder then they're equal.
218-
Some((0, placeholder)) => {
219-
return ty::Region::new_placeholder(tcx, placeholder);
220-
}
221-
216+
let annotation = self.constraint_sccs.annotation(scc);
217+
if annotation.representative_is_placeholder && vid == annotation.representative
218+
{
219+
// FIXME: somehow construct the right type out of the representative!
220+
return region;
221+
} else {
222222
// Fallback: this will produce a cryptic error message.
223-
_ => return region,
223+
return region;
224224
}
225225
}
226226

compiler/rustc_borrowck/src/region_infer/values.rs

Lines changed: 3 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ pub(crate) enum RegionElement {
2828
/// A universally quantified region from the root universe (e.g.,
2929
/// a lifetime parameter).
3030
RootUniversalRegion(RegionVid),
31-
32-
/// A placeholder (e.g., instantiated from a `for<'a> fn(&'a u32)`
33-
/// type).
34-
PlaceholderRegion(ty::PlaceholderRegion),
3531
}
3632

3733
/// Records the CFG locations where each region is live. When we initially compute liveness, we use
@@ -223,21 +219,6 @@ impl PlaceholderIndices {
223219
let (index, _) = self.indices.insert_full(placeholder);
224220
index.into()
225221
}
226-
227-
pub(crate) fn lookup_index(&self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex {
228-
self.indices.get_index_of(&placeholder).unwrap().into()
229-
}
230-
231-
pub(crate) fn lookup_placeholder(
232-
&self,
233-
placeholder: PlaceholderIndex,
234-
) -> ty::PlaceholderRegion {
235-
self.indices[placeholder.index()]
236-
}
237-
238-
pub(crate) fn len(&self) -> usize {
239-
self.indices.len()
240-
}
241222
}
242223

243224
/// Stores the full values for a set of regions (in contrast to
@@ -261,31 +242,19 @@ impl PlaceholderIndices {
261242
#[derive(Clone)]
262243
pub(crate) struct RegionValues<N: Idx> {
263244
elements: Rc<DenseLocationMap>,
264-
placeholder_indices: Rc<PlaceholderIndices>,
265245
points: SparseIntervalMatrix<N, PointIndex>,
266246
free_regions: SparseBitMatrix<N, RegionVid>,
267-
268-
/// Placeholders represent bound regions -- so something like `'a`
269-
/// in `for<'a> fn(&'a u32)`.
270-
placeholders: SparseBitMatrix<N, PlaceholderIndex>,
271247
}
272248

273249
impl<N: Idx> RegionValues<N> {
274250
/// Creates a new set of "region values" that tracks causal information.
275251
/// Each of the regions in num_region_variables will be initialized with an
276252
/// empty set of points and no causal information.
277-
pub(crate) fn new(
278-
elements: &Rc<DenseLocationMap>,
279-
num_universal_regions: usize,
280-
placeholder_indices: &Rc<PlaceholderIndices>,
281-
) -> Self {
282-
let num_placeholders = placeholder_indices.len();
253+
pub(crate) fn new(elements: &Rc<DenseLocationMap>, num_universal_regions: usize) -> Self {
283254
Self {
284255
elements: elements.clone(),
285256
points: SparseIntervalMatrix::new(elements.num_points()),
286-
placeholder_indices: placeholder_indices.clone(),
287257
free_regions: SparseBitMatrix::new(num_universal_regions),
288-
placeholders: SparseBitMatrix::new(num_placeholders),
289258
}
290259
}
291260

@@ -304,9 +273,7 @@ impl<N: Idx> RegionValues<N> {
304273
/// Adds all elements in `r_from` to `r_to` (because e.g., `r_to:
305274
/// r_from`).
306275
pub(crate) fn add_region(&mut self, r_to: N, r_from: N) -> bool {
307-
self.points.union_rows(r_from, r_to)
308-
| self.free_regions.union_rows(r_from, r_to)
309-
| self.placeholders.union_rows(r_from, r_to)
276+
self.points.union_rows(r_from, r_to) | self.free_regions.union_rows(r_from, r_to)
310277
}
311278

312279
/// Returns `true` if the region `r` contains the given element.
@@ -375,18 +342,6 @@ impl<N: Idx> RegionValues<N> {
375342
self.free_regions.row(r).into_iter().flat_map(|set| set.iter())
376343
}
377344

378-
/// Returns all the elements contained in a given region's value.
379-
pub(crate) fn placeholders_contained_in<'a>(
380-
&'a self,
381-
r: N,
382-
) -> impl Iterator<Item = ty::PlaceholderRegion> + 'a {
383-
self.placeholders
384-
.row(r)
385-
.into_iter()
386-
.flat_map(|set| set.iter())
387-
.map(move |p| self.placeholder_indices.lookup_placeholder(p))
388-
}
389-
390345
/// Returns all the elements contained in a given region's value.
391346
pub(crate) fn elements_contained_in<'a>(
392347
&'a self,
@@ -397,10 +352,7 @@ impl<N: Idx> RegionValues<N> {
397352
let free_regions_iter =
398353
self.universal_regions_outlived_by(r).map(RegionElement::RootUniversalRegion);
399354

400-
let placeholder_universes_iter =
401-
self.placeholders_contained_in(r).map(RegionElement::PlaceholderRegion);
402-
403-
points_iter.chain(free_regions_iter).chain(placeholder_universes_iter)
355+
points_iter.chain(free_regions_iter)
404356
}
405357

406358
/// Returns a "pretty" string value of the region. Meant for debugging.
@@ -437,18 +389,6 @@ impl ToElementIndex for RegionVid {
437389
}
438390
}
439391

440-
impl ToElementIndex for ty::PlaceholderRegion {
441-
fn add_to_row<N: Idx>(self, values: &mut RegionValues<N>, row: N) -> bool {
442-
let index = values.placeholder_indices.lookup_index(self);
443-
values.placeholders.insert(row, index)
444-
}
445-
446-
fn contained_in_row<N: Idx>(self, values: &RegionValues<N>, row: N) -> bool {
447-
let index = values.placeholder_indices.lookup_index(self);
448-
values.placeholders.contains(row, index)
449-
}
450-
}
451-
452392
/// For debugging purposes, returns a pretty-printed string of the given points.
453393
pub(crate) fn pretty_print_points(
454394
elements: &DenseLocationMap,
@@ -508,17 +448,6 @@ fn pretty_print_region_elements(elements: impl IntoIterator<Item = RegionElement
508448
push_sep(&mut result);
509449
result.push_str(&format!("{fr:?}"));
510450
}
511-
512-
RegionElement::PlaceholderRegion(placeholder) => {
513-
if let Some((location1, location2)) = open_location {
514-
push_sep(&mut result);
515-
push_location_range(&mut result, location1, location2);
516-
open_location = None;
517-
}
518-
519-
push_sep(&mut result);
520-
result.push_str(&format!("{placeholder:?}"));
521-
}
522451
}
523452
}
524453

0 commit comments

Comments
 (0)