Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 8 additions & 10 deletions compiler/rustc_borrowck/src/handle_placeholders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,18 @@ pub(crate) struct LoweredConstraints<'tcx> {
pub(crate) placeholder_indices: PlaceholderIndices<'tcx>,
}

impl<'d, 'tcx, A: scc::Annotation> SccAnnotations<'d, 'tcx, A> {
pub(crate) fn init(definitions: &'d IndexVec<RegionVid, RegionDefinition<'tcx>>) -> Self {
Self { scc_to_annotation: IndexVec::new(), definitions }
}
}

/// A Visitor for SCC annotation construction.
pub(crate) struct SccAnnotations<'d, 'tcx, A: scc::Annotation> {
pub(crate) scc_to_annotation: IndexVec<ConstraintSccIndex, A>,
definitions: &'d IndexVec<RegionVid, RegionDefinition<'tcx>>,
}

impl<'d, 'tcx, A: scc::Annotation> SccAnnotations<'d, 'tcx, A> {
pub(crate) fn init(definitions: &'d IndexVec<RegionVid, RegionDefinition<'tcx>>) -> Self {
Self { scc_to_annotation: IndexVec::new(), definitions }
}
}

impl scc::Annotations<RegionVid> for SccAnnotations<'_, '_, RegionTracker> {
fn new(&self, element: RegionVid) -> RegionTracker {
RegionTracker::new(element, &self.definitions[element])
Expand Down Expand Up @@ -118,7 +118,7 @@ impl RegionTracker {
}

/// The largest universe this SCC can name. It's the smallest
/// largest nameable universe of any reachable region, or
/// max-nameable-universe of any reachable region, or
/// `max_nameable(r) = min (max_nameable(r') for r' reachable from r)`
pub(crate) fn max_nameable_universe(self) -> UniverseIndex {
self.max_nameable_universe.0
Expand Down Expand Up @@ -208,7 +208,7 @@ pub(super) fn region_definitions<'tcx>(
/// graph such that there is a series of constraints
/// A: B: C: ... : X where
/// A contains a placeholder whose universe cannot be named by X,
/// add a constraint that A: 'static. This is a safe upper bound
/// add a constraint that X: 'static. This is a safe upper bound
/// in the face of borrow checker/trait solver limitations that will
/// eventually go away.
///
Expand Down Expand Up @@ -327,8 +327,6 @@ pub(crate) fn rewrite_placeholder_outlives<'tcx>(

for scc in sccs.all_sccs() {
// No point in adding 'static: 'static!
// This micro-optimisation makes somewhat sense
// because static outlives *everything*.
if scc == sccs.scc(fr_static) {
continue;
}
Expand Down
31 changes: 18 additions & 13 deletions compiler/rustc_borrowck/src/region_infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -501,43 +501,48 @@ impl<'tcx> RegionInferenceContext<'tcx> {

let mut errors_buffer = RegionErrors::new(infcx.tcx);

// If this is a closure, we can propagate unsatisfied
// `outlives_requirements` to our creator, so create a vector
// to store those. Otherwise, we'll pass in `None` to the
// functions below, which will trigger them to report errors
// eagerly.
let mut outlives_requirements = infcx.tcx.is_typeck_child(mir_def_id).then(Vec::new);
// If this is a nested body, we propagate unsatisfied
// outlives constraints to the parent body instead of
// eagerly erroing.
let mut propagated_outlives_requirements =
infcx.tcx.is_typeck_child(mir_def_id).then(Vec::new);

self.check_type_tests(infcx, outlives_requirements.as_mut(), &mut errors_buffer);
self.check_type_tests(infcx, propagated_outlives_requirements.as_mut(), &mut errors_buffer);

debug!(?errors_buffer);
debug!(?outlives_requirements);
debug!(?propagated_outlives_requirements);

// In Polonius mode, the errors about missing universal region relations are in the output
// and need to be emitted or propagated. Otherwise, we need to check whether the
// constraints were too strong, and if so, emit or propagate those errors.
if infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() {
self.check_polonius_subset_errors(
outlives_requirements.as_mut(),
propagated_outlives_requirements.as_mut(),
&mut errors_buffer,
polonius_output
.as_ref()
.expect("Polonius output is unavailable despite `-Z polonius`"),
);
} else {
self.check_universal_regions(outlives_requirements.as_mut(), &mut errors_buffer);
self.check_universal_regions(
propagated_outlives_requirements.as_mut(),
&mut errors_buffer,
);
}

debug!(?errors_buffer);

let outlives_requirements = outlives_requirements.unwrap_or_default();
let propagated_outlives_requirements = propagated_outlives_requirements.unwrap_or_default();

if outlives_requirements.is_empty() {
if propagated_outlives_requirements.is_empty() {
(None, errors_buffer)
} else {
let num_external_vids = self.universal_regions().num_global_and_external_regions();
(
Some(ClosureRegionRequirements { num_external_vids, outlives_requirements }),
Some(ClosureRegionRequirements {
num_external_vids,
outlives_requirements: propagated_outlives_requirements,
}),
errors_buffer,
)
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_data_structures/src/graph/scc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ mod tests;
/// the max/min element of the SCC, or all of the above.
///
/// Concretely, the both merge operations must commute, e.g. where `merge`
/// is `update_scc` and `update_reached`: `a.merge(b) == b.merge(a)`
/// is `update_scc` and `update_reachable`: `a.merge(b) == b.merge(a)`
///
/// In general, what you want is probably always min/max according
/// to some ordering, potentially with side constraints (min x such
Expand Down
Loading