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

Commit 4df04ed

Browse files
committed
Preliminary attempt at removing placeholders out of the borrow checker.
This version is maximally naive, and currently unsound.
1 parent 01e2fff commit 4df04ed

File tree

5 files changed

+32
-149
lines changed

5 files changed

+32
-149
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))
@@ -985,7 +981,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
985981
//
986982
// It doesn't matter *what* universe because the promoted `T` will
987983
// always be in the root universe.
988-
if let Some(p) = self.scc_values.placeholders_contained_in(r_scc).next() {
984+
985+
if let Some(p) = self.constraint_sccs.annotation(r_scc).placeholder_representative() {
989986
debug!("encountered placeholder in higher universe: {:?}, requiring 'static", p);
990987
let static_r = self.universal_regions.fr_static;
991988
propagated_outlives_requirements.push(ClosureOutlivesRequirement {
@@ -1651,14 +1648,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
16511648
for error_element in self.scc_values.elements_contained_in(longer_fr_scc) {
16521649
match error_element {
16531650
RegionElement::Location(_) | RegionElement::RootUniversalRegion(_) => {}
1654-
// If we have some bound universal region `'a`, then the only
1655-
// elements it can contain is itself -- we don't know anything
1656-
// else about it!
1657-
RegionElement::PlaceholderRegion(placeholder1) => {
1658-
if placeholder == placeholder1 {
1659-
continue;
1660-
}
1661-
}
16621651
}
16631652

16641653
errors_buffer.push(RegionErrorKind::BoundUniversalRegionError {
@@ -1925,14 +1914,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
19251914
match *element {
19261915
RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l),
19271916
RegionElement::RootUniversalRegion(r) => r,
1928-
RegionElement::PlaceholderRegion(error_placeholder) => self
1929-
.definitions
1930-
.iter_enumerated()
1931-
.find_map(|(r, definition)| match definition.origin {
1932-
NllRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r),
1933-
_ => None,
1934-
})
1935-
.unwrap(),
19361917
}
19371918
}
19381919

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: 5 additions & 77 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,32 +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_points = elements.num_points();
283-
let num_placeholders = placeholder_indices.len();
253+
pub(crate) fn new(elements: &Rc<DenseLocationMap>, num_universal_regions: usize) -> Self {
284254
Self {
285-
elements,
286-
points: SparseIntervalMatrix::new(num_points),
287-
placeholder_indices,
255+
elements: elements.clone(),
256+
points: SparseIntervalMatrix::new(elements.num_points()),
288257
free_regions: SparseBitMatrix::new(num_universal_regions),
289-
placeholders: SparseBitMatrix::new(num_placeholders),
290258
}
291259
}
292260

@@ -305,9 +273,7 @@ impl<N: Idx> RegionValues<N> {
305273
/// Adds all elements in `r_from` to `r_to` (because e.g., `r_to:
306274
/// r_from`).
307275
pub(crate) fn add_region(&mut self, r_to: N, r_from: N) -> bool {
308-
self.points.union_rows(r_from, r_to)
309-
| self.free_regions.union_rows(r_from, r_to)
310-
| 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)
311277
}
312278

313279
/// Returns `true` if the region `r` contains the given element.
@@ -376,18 +342,6 @@ impl<N: Idx> RegionValues<N> {
376342
self.free_regions.row(r).into_iter().flat_map(|set| set.iter())
377343
}
378344

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

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

407358
/// Returns a "pretty" string value of the region. Meant for debugging.
@@ -438,18 +389,6 @@ impl ToElementIndex for RegionVid {
438389
}
439390
}
440391

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

0 commit comments

Comments
 (0)