Skip to content

Commit 698631c

Browse files
committed
Preliminary attempt at removing placeholders out of the borrow checker.
This version is maximally naive, and currently unsound.
1 parent 6cf068d commit 698631c

File tree

5 files changed

+30
-147
lines changed

5 files changed

+30
-147
lines changed

compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -180,20 +180,7 @@ trait TypeOpInfo<'tcx> {
180180
ty::Placeholder { universe: adjusted_universe.into(), bound: placeholder.bound },
181181
);
182182

183-
let error_region = if let RegionElement::PlaceholderRegion(error_placeholder) =
184-
error_element
185-
{
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(
190-
tcx,
191-
ty::Placeholder { universe: adjusted.into(), bound: error_placeholder.bound },
192-
)
193-
})
194-
} else {
195-
None
196-
};
183+
let error_region = None;
197184

198185
debug!(?placeholder_region);
199186

compiler/rustc_borrowck/src/diagnostics/region_errors.rs

+8-22
Original file line numberDiff line numberDiff line change
@@ -203,35 +203,20 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
203203
fn suggest_static_lifetime_for_gat_from_hrtb(
204204
&self,
205205
diag: &mut Diag<'_>,
206-
lower_bound: RegionVid,
206+
_lower_bound: RegionVid,
207207
) {
208208
let mut suggestions = vec![];
209209
let hir = self.infcx.tcx.hir();
210210

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

233217
// find higher-ranked trait bounds bounded to the generic associated types
234-
let mut hrtb_bounds = vec![];
218+
let hrtb_bounds = vec![];
219+
/*
235220
gat_id_and_generics.iter().flatten().for_each(|(gat_hir_id, generics)| {
236221
for pred in generics.predicates {
237222
let BoundPredicate(WhereBoundPredicate { bound_generic_params, bounds, .. }) = pred
@@ -250,6 +235,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
250235
}
251236
});
252237
debug!(?hrtb_bounds);
238+
*/
253239

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

compiler/rustc_borrowck/src/region_infer/mod.rs

+11-30
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ impl RegionTracker {
115115
}
116116
}
117117

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

431-
let mut scc_values =
432-
RegionValues::new(elements, universal_regions.len(), &placeholder_indices);
437+
let mut scc_values = RegionValues::new(elements, universal_regions.len());
433438

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

543-
NllRegionVariableOrigin::Placeholder(placeholder) => {
544-
self.scc_values.add_element(scc, placeholder);
548+
NllRegionVariableOrigin::Placeholder { .. } => {
549+
// Placeholders are already handled by rewriting constraints.
545550
}
546-
547551
NllRegionVariableOrigin::Existential { .. } => {
548552
// For existential, regions, nothing to do.
549553
}
@@ -602,14 +606,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
602606
self.scc_values.region_value_str(scc)
603607
}
604608

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

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

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -212,14 +212,14 @@ impl<'tcx> RegionInferenceContext<'tcx> {
212212

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

compiler/rustc_borrowck/src/region_infer/values.rs

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

3632
/// Records the CFG locations where each region is live. When we initially compute liveness, we use
@@ -226,21 +222,6 @@ impl PlaceholderIndices {
226222
let (index, _) = self.indices.insert_full(placeholder);
227223
index.into()
228224
}
229-
230-
pub(crate) fn lookup_index(&self, placeholder: ty::PlaceholderRegion) -> PlaceholderIndex {
231-
self.indices.get_index_of(&placeholder).unwrap().into()
232-
}
233-
234-
pub(crate) fn lookup_placeholder(
235-
&self,
236-
placeholder: PlaceholderIndex,
237-
) -> ty::PlaceholderRegion {
238-
self.indices[placeholder.index()]
239-
}
240-
241-
pub(crate) fn len(&self) -> usize {
242-
self.indices.len()
243-
}
244225
}
245226

246227
/// Stores the full values for a set of regions (in contrast to
@@ -264,31 +245,19 @@ impl PlaceholderIndices {
264245
#[derive(Clone)]
265246
pub(crate) struct RegionValues<N: Idx> {
266247
elements: Rc<DenseLocationMap>,
267-
placeholder_indices: Rc<PlaceholderIndices>,
268248
points: SparseIntervalMatrix<N, PointIndex>,
269249
free_regions: SparseBitMatrix<N, RegionVid>,
270-
271-
/// Placeholders represent bound regions -- so something like `'a`
272-
/// in `for<'a> fn(&'a u32)`.
273-
placeholders: SparseBitMatrix<N, PlaceholderIndex>,
274250
}
275251

276252
impl<N: Idx> RegionValues<N> {
277253
/// Creates a new set of "region values" that tracks causal information.
278254
/// Each of the regions in num_region_variables will be initialized with an
279255
/// empty set of points and no causal information.
280-
pub(crate) fn new(
281-
elements: &Rc<DenseLocationMap>,
282-
num_universal_regions: usize,
283-
placeholder_indices: &Rc<PlaceholderIndices>,
284-
) -> Self {
285-
let num_placeholders = placeholder_indices.len();
256+
pub(crate) fn new(elements: &Rc<DenseLocationMap>, num_universal_regions: usize) -> Self {
286257
Self {
287258
elements: elements.clone(),
288259
points: SparseIntervalMatrix::new(elements.num_points()),
289-
placeholder_indices: placeholder_indices.clone(),
290260
free_regions: SparseBitMatrix::new(num_universal_regions),
291-
placeholders: SparseBitMatrix::new(num_placeholders),
292261
}
293262
}
294263

@@ -307,9 +276,7 @@ impl<N: Idx> RegionValues<N> {
307276
/// Adds all elements in `r_from` to `r_to` (because e.g., `r_to:
308277
/// r_from`).
309278
pub(crate) fn add_region(&mut self, r_to: N, r_from: N) -> bool {
310-
self.points.union_rows(r_from, r_to)
311-
| self.free_regions.union_rows(r_from, r_to)
312-
| self.placeholders.union_rows(r_from, r_to)
279+
self.points.union_rows(r_from, r_to) | self.free_regions.union_rows(r_from, r_to)
313280
}
314281

315282
/// Returns `true` if the region `r` contains the given element.
@@ -378,18 +345,6 @@ impl<N: Idx> RegionValues<N> {
378345
self.free_regions.row(r).into_iter().flat_map(|set| set.iter())
379346
}
380347

381-
/// Returns all the elements contained in a given region's value.
382-
pub(crate) fn placeholders_contained_in<'a>(
383-
&'a self,
384-
r: N,
385-
) -> impl Iterator<Item = ty::PlaceholderRegion> + 'a {
386-
self.placeholders
387-
.row(r)
388-
.into_iter()
389-
.flat_map(|set| set.iter())
390-
.map(move |p| self.placeholder_indices.lookup_placeholder(p))
391-
}
392-
393348
/// Returns all the elements contained in a given region's value.
394349
pub(crate) fn elements_contained_in<'a>(
395350
&'a self,
@@ -400,10 +355,7 @@ impl<N: Idx> RegionValues<N> {
400355
let free_regions_iter =
401356
self.universal_regions_outlived_by(r).map(RegionElement::RootUniversalRegion);
402357

403-
let placeholder_universes_iter =
404-
self.placeholders_contained_in(r).map(RegionElement::PlaceholderRegion);
405-
406-
points_iter.chain(free_regions_iter).chain(placeholder_universes_iter)
358+
points_iter.chain(free_regions_iter)
407359
}
408360

409361
/// Returns a "pretty" string value of the region. Meant for debugging.
@@ -440,18 +392,6 @@ impl ToElementIndex for RegionVid {
440392
}
441393
}
442394

443-
impl ToElementIndex for ty::PlaceholderRegion {
444-
fn add_to_row<N: Idx>(self, values: &mut RegionValues<N>, row: N) -> bool {
445-
let index = values.placeholder_indices.lookup_index(self);
446-
values.placeholders.insert(row, index)
447-
}
448-
449-
fn contained_in_row<N: Idx>(self, values: &RegionValues<N>, row: N) -> bool {
450-
let index = values.placeholder_indices.lookup_index(self);
451-
values.placeholders.contains(row, index)
452-
}
453-
}
454-
455395
/// For debugging purposes, returns a pretty-printed string of the given points.
456396
pub(crate) fn pretty_print_points(
457397
elements: &DenseLocationMap,
@@ -511,17 +451,6 @@ fn pretty_print_region_elements(elements: impl IntoIterator<Item = RegionElement
511451
push_sep(&mut result);
512452
result.push_str(&format!("{fr:?}"));
513453
}
514-
515-
RegionElement::PlaceholderRegion(placeholder) => {
516-
if let Some((location1, location2)) = open_location {
517-
push_sep(&mut result);
518-
push_location_range(&mut result, location1, location2);
519-
open_location = None;
520-
}
521-
522-
push_sep(&mut result);
523-
result.push_str(&format!("{placeholder:?}"));
524-
}
525454
}
526455
}
527456

0 commit comments

Comments
 (0)