Skip to content

Commit fbea9f0

Browse files
committed
WIP: manual rebase
1 parent 199f961 commit fbea9f0

File tree

5 files changed

+55
-194
lines changed

5 files changed

+55
-194
lines changed

compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,6 @@ pub(crate) trait TypeOpInfo<'tcx> {
179179
cause: ObligationCause<'tcx>,
180180
) {
181181
let tcx = mbcx.infcx.tcx;
182-
183182
// FIXME: these adjusted universes are not (always) the same ones as we compute
184183
// earlier. They probably should be, but the logic downstream is complicated,
185184
// and assumes they use whatever this is.

compiler/rustc_borrowck/src/handle_placeholders.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ impl scc::Annotations<RegionVid> for SccAnnotations<'_, '_, RegionTracker> {
6969
}
7070

7171
#[derive(Copy, Debug, Clone, PartialEq, Eq)]
72-
enum PlaceholderReachability {
72+
pub(crate) enum PlaceholderReachability {
7373
/// This SCC reaches no placeholders.
7474
NoPlaceholders,
7575
/// This SCC reaches at least one placeholder.
@@ -218,6 +218,10 @@ impl RegionTracker {
218218
PlaceholderReachability::Placeholders { min_placeholder, .. } => Some(min_placeholder),
219219
}
220220
}
221+
222+
pub(crate) fn reachable_placeholders(&self) -> PlaceholderReachability {
223+
self.reachable_placeholders
224+
}
221225
}
222226
/// Pick the smallest universe index out of two, preferring
223227
/// the first argument if they are equal.

compiler/rustc_borrowck/src/region_infer/mod.rs

Lines changed: 41 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ use crate::constraints::graph::{self, NormalConstraintGraph, RegionGraph};
2828
use crate::constraints::{ConstraintSccIndex, OutlivesConstraint, OutlivesConstraintSet};
2929
use crate::dataflow::BorrowIndex;
3030
use crate::diagnostics::{RegionErrorKind, RegionErrors, UniverseInfo};
31-
use crate::handle_placeholders::{LoweredConstraints, RegionTracker};
31+
use crate::handle_placeholders::{LoweredConstraints, PlaceholderReachability, RegionTracker};
3232
use crate::member_constraints::{MemberConstraintSet, NllMemberConstraintIndex};
3333
use crate::polonius::LiveLoans;
3434
use crate::polonius::legacy::PoloniusOutput;
@@ -360,7 +360,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
360360
outlives_constraints,
361361
scc_annotations,
362362
type_tests,
363-
liveness_constraints,
363+
mut liveness_constraints,
364364
universe_causes,
365365
placeholder_indices,
366366
member_constraints,
@@ -377,8 +377,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
377377
sccs_info(infcx, &constraint_sccs);
378378
}
379379

380-
let mut scc_values =
381-
RegionValues::new(location_map, universal_regions.len(), placeholder_indices);
380+
let mut scc_values = RegionValues::new(location_map, universal_regions.len());
382381

383382
for region in liveness_constraints.regions() {
384383
let scc = constraint_sccs.scc(region);
@@ -388,7 +387,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
388387
let member_constraints =
389388
Rc::new(member_constraints.into_mapped(|r| constraint_sccs.scc(r)));
390389

391-
let mut result = Self {
390+
for variable in definitions.indices() {
391+
if let NllRegionVariableOrigin::FreeRegion = definitions[variable].origin {
392+
// For each free, universally quantified region X:
393+
394+
let scc = constraint_sccs.scc(variable);
395+
396+
// Add all nodes in the CFG to liveness constraints
397+
liveness_constraints.add_all_points(variable);
398+
scc_values.add_all_points(scc);
399+
400+
// Add `end(X)` into the set for X.
401+
scc_values.add_element(scc, variable);
402+
}
403+
}
404+
405+
Self {
392406
definitions,
393407
liveness_constraints,
394408
constraints: outlives_constraints,
@@ -402,90 +416,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
402416
scc_values,
403417
type_tests,
404418
universal_region_relations,
405-
};
406-
407-
result.init_free_and_bound_regions();
408-
409-
result
410-
}
411-
412-
/// Initializes the region variables for each universally
413-
/// quantified region (lifetime parameter). The first N variables
414-
/// always correspond to the regions appearing in the function
415-
/// signature (both named and anonymous) and where-clauses. This
416-
/// function iterates over those regions and initializes them with
417-
/// minimum values.
418-
///
419-
/// For example:
420-
/// ```
421-
/// fn foo<'a, 'b>( /* ... */ ) where 'a: 'b { /* ... */ }
422-
/// ```
423-
/// would initialize two variables like so:
424-
/// ```ignore (illustrative)
425-
/// R0 = { CFG, R0 } // 'a
426-
/// R1 = { CFG, R0, R1 } // 'b
427-
/// ```
428-
/// Here, R0 represents `'a`, and it contains (a) the entire CFG
429-
/// and (b) any universally quantified regions that it outlives,
430-
/// which in this case is just itself. R1 (`'b`) in contrast also
431-
/// outlives `'a` and hence contains R0 and R1.
432-
///
433-
/// This bit of logic also handles invalid universe relations
434-
/// for higher-kinded types.
435-
///
436-
/// We Walk each SCC `A` and `B` such that `A: B`
437-
/// and ensure that universe(A) can see universe(B).
438-
///
439-
/// This serves to enforce the 'empty/placeholder' hierarchy
440-
/// (described in more detail on `RegionKind`):
441-
///
442-
/// ```ignore (illustrative)
443-
/// static -----+
444-
/// | |
445-
/// empty(U0) placeholder(U1)
446-
/// | /
447-
/// empty(U1)
448-
/// ```
449-
///
450-
/// In particular, imagine we have variables R0 in U0 and R1
451-
/// created in U1, and constraints like this;
452-
///
453-
/// ```ignore (illustrative)
454-
/// R1: !1 // R1 outlives the placeholder in U1
455-
/// R1: R0 // R1 outlives R0
456-
/// ```
457-
///
458-
/// Here, we wish for R1 to be `'static`, because it
459-
/// cannot outlive `placeholder(U1)` and `empty(U0)` any other way.
460-
///
461-
/// Thanks to this loop, what happens is that the `R1: R0`
462-
/// constraint has lowered the universe of `R1` to `U0`, which in turn
463-
/// means that the `R1: !1` constraint here will cause
464-
/// `R1` to become `'static`.
465-
fn init_free_and_bound_regions(&mut self) {
466-
for variable in self.definitions.indices() {
467-
let scc = self.constraint_sccs.scc(variable);
468-
469-
match self.definitions[variable].origin {
470-
NllRegionVariableOrigin::FreeRegion => {
471-
// For each free, universally quantified region X:
472-
473-
// Add all nodes in the CFG to liveness constraints
474-
self.liveness_constraints.add_all_points(variable);
475-
self.scc_values.add_all_points(scc);
476-
477-
// Add `end(X)` into the set for X.
478-
self.scc_values.add_element(scc, variable);
479-
}
480-
481-
NllRegionVariableOrigin::Placeholder(placeholder) => {
482-
self.scc_values.add_element(scc, placeholder);
483-
}
484-
485-
NllRegionVariableOrigin::Existential { .. } => {
486-
// For existential, regions, nothing to do.
487-
}
488-
}
489419
}
490420
}
491421

@@ -542,14 +472,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
542472
self.scc_values.region_value_str(scc)
543473
}
544474

545-
pub(crate) fn placeholders_contained_in(
546-
&self,
547-
r: RegionVid,
548-
) -> impl Iterator<Item = ty::PlaceholderRegion> {
549-
let scc = self.constraint_sccs.scc(r);
550-
self.scc_values.placeholders_contained_in(scc)
551-
}
552-
553475
/// Once region solving has completed, this function will return the member constraints that
554476
/// were applied to the value of a given SCC `scc`. See `AppliedMemberConstraint`.
555477
pub(crate) fn applied_member_constraints(
@@ -901,8 +823,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
901823
//
902824
// It doesn't matter *what* universe because the promoted `T` will
903825
// always be in the root universe.
904-
if let Some(p) = self.scc_values.placeholders_contained_in(r_scc).next() {
905-
debug!("encountered placeholder in higher universe: {:?}, requiring 'static", p);
826+
if let PlaceholderReachability::Placeholders { min_placeholder, .. } =
827+
self.scc_annotations[r_scc].reachable_placeholders()
828+
{
829+
debug!(
830+
"encountered placeholder in higher universe: {min_placeholder:?}, requiring 'static"
831+
);
832+
906833
let static_r = self.universal_regions().fr_static;
907834
propagated_outlives_requirements.push(ClosureOutlivesRequirement {
908835
subject,
@@ -1792,14 +1719,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
17921719
match *element {
17931720
RegionElement::Location(l) => self.find_sub_region_live_at(longer_fr, l),
17941721
RegionElement::RootUniversalRegion(r) => r,
1795-
RegionElement::PlaceholderRegion(error_placeholder) => self
1796-
.definitions
1797-
.iter_enumerated()
1798-
.find_map(|(r, definition)| match definition.origin {
1799-
NllRegionVariableOrigin::Placeholder(p) if p == error_placeholder => Some(r),
1800-
_ => None,
1801-
})
1802-
.unwrap(),
18031722
}
18041723
}
18051724

@@ -2082,6 +2001,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
20822001
self.scc_annotations[scc].representative.rvid()
20832002
}
20842003

2004+
/// If the representative of an SCC is a placeholder, return
2005+
/// its originating `PlaceholderRegion`.
2006+
pub(crate) fn placeholder_representative(
2007+
&self,
2008+
scc: ConstraintSccIndex,
2009+
) -> Option<ty::PlaceholderRegion> {
2010+
if let Representative::Placeholder(r) = self.scc_annotations[scc].representative
2011+
&& let NllRegionVariableOrigin::Placeholder(p) = self.definitions[r].origin
2012+
{
2013+
Some(p)
2014+
} else {
2015+
None
2016+
}
2017+
}
2018+
20852019
pub(crate) fn liveness_constraints(&self) -> &LivenessValues {
20862020
&self.liveness_constraints
20872021
}

compiler/rustc_borrowck/src/region_infer/opaque_types.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -190,17 +190,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
190190
ty::ReVar(vid) => {
191191
let scc = self.constraint_sccs.scc(vid);
192192

193-
// Special handling of higher-ranked regions.
194-
if !self.max_nameable_universe(scc).is_root() {
195-
match self.scc_values.placeholders_contained_in(scc).enumerate().last() {
196-
// If the region contains a single placeholder then they're equal.
197-
Some((0, placeholder)) => {
198-
return ty::Region::new_placeholder(tcx, placeholder);
199-
}
200-
201-
// Fallback: this will produce a cryptic error message.
202-
_ => return region,
203-
}
193+
if let Some(representative) = self.placeholder_representative(scc) {
194+
return ty::Region::new_placeholder(tcx, representative);
204195
}
205196

206197
// Find something that we can name

0 commit comments

Comments
 (0)