summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_borrowck/src/region_infer/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_borrowck/src/region_infer/mod.rs')
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs63
1 files changed, 51 insertions, 12 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 852935676..b1f91a056 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -7,6 +7,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::graph::scc::Sccs;
use rustc_errors::Diagnostic;
use rustc_hir::def_id::CRATE_DEF_ID;
+use rustc_index::bit_set::SparseBitMatrix;
use rustc_index::{IndexSlice, IndexVec};
use rustc_infer::infer::outlives::test_type_match;
use rustc_infer::infer::region_constraints::{GenericKind, VarInfos, VerifyBound, VerifyIfEq};
@@ -21,17 +22,17 @@ use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
use rustc_span::Span;
+use crate::constraints::graph::{self, NormalConstraintGraph, RegionGraph};
+use crate::dataflow::BorrowIndex;
use crate::{
- constraints::{
- graph::NormalConstraintGraph, ConstraintSccIndex, OutlivesConstraint, OutlivesConstraintSet,
- },
+ constraints::{ConstraintSccIndex, OutlivesConstraint, OutlivesConstraintSet},
diagnostics::{RegionErrorKind, RegionErrors, UniverseInfo},
member_constraints::{MemberConstraintSet, NllMemberConstraintIndex},
nll::PoloniusOutput,
region_infer::reverse_sccs::ReverseSccGraph,
region_infer::values::{
- LivenessValues, PlaceholderIndices, RegionElement, RegionValueElements, RegionValues,
- ToElementIndex,
+ LivenessValues, PlaceholderIndices, PointIndex, RegionElement, RegionValueElements,
+ RegionValues, ToElementIndex,
},
type_check::{free_region_relations::UniversalRegionRelations, Locations},
universal_regions::UniversalRegions,
@@ -119,6 +120,9 @@ pub struct RegionInferenceContext<'tcx> {
/// Information about how the universally quantified regions in
/// scope on this function relate to one another.
universal_region_relations: Frozen<UniversalRegionRelations<'tcx>>,
+
+ /// The set of loans that are live at a given point in the CFG, when using `-Zpolonius=next`.
+ live_loans: SparseBitMatrix<PointIndex, BorrowIndex>,
}
/// Each time that `apply_member_constraint` is successful, it appends
@@ -330,6 +334,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
type_tests: Vec<TypeTest<'tcx>>,
liveness_constraints: LivenessValues<RegionVid>,
elements: &Rc<RegionValueElements>,
+ live_loans: SparseBitMatrix<PointIndex, BorrowIndex>,
) -> Self {
debug!("universal_regions: {:#?}", universal_regions);
debug!("outlives constraints: {:#?}", outlives_constraints);
@@ -383,6 +388,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
type_tests,
universal_regions,
universal_region_relations,
+ live_loans,
};
result.init_free_and_bound_regions();
@@ -637,11 +643,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
self.scc_universes[scc]
}
- /// Once region solving has completed, this function will return
- /// the member constraints that were applied to the value of a given
- /// region `r`. See `AppliedMemberConstraint`.
- pub(crate) fn applied_member_constraints(&self, r: RegionVid) -> &[AppliedMemberConstraint] {
- let scc = self.constraint_sccs.scc(r);
+ /// Once region solving has completed, this function will return the member constraints that
+ /// were applied to the value of a given SCC `scc`. See `AppliedMemberConstraint`.
+ pub(crate) fn applied_member_constraints(
+ &self,
+ scc: ConstraintSccIndex,
+ ) -> &[AppliedMemberConstraint] {
binary_search_util::binary_search_slice(
&self.member_constraints_applied,
|applied| applied.member_region_scc,
@@ -683,7 +690,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// 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 {
+ if infcx.tcx.sess.opts.unstable_opts.polonius.is_legacy_enabled() {
self.check_polonius_subset_errors(
outlives_requirements.as_mut(),
&mut errors_buffer,
@@ -1938,7 +1945,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// Member constraints can also give rise to `'r: 'x` edges that
// were not part of the graph initially, so watch out for those.
// (But they are extremely rare; this loop is very cold.)
- for constraint in self.applied_member_constraints(r) {
+ for constraint in self.applied_member_constraints(self.constraint_sccs.scc(r)) {
let p_c = &self.member_constraints[constraint.member_constraint_index];
let constraint = OutlivesConstraint {
sup: r,
@@ -2279,6 +2286,38 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}
None
}
+
+ /// Access to the SCC constraint graph.
+ pub(crate) fn constraint_sccs(&self) -> &Sccs<RegionVid, ConstraintSccIndex> {
+ self.constraint_sccs.as_ref()
+ }
+
+ /// Access to the region graph, built from the outlives constraints.
+ pub(crate) fn region_graph(&self) -> RegionGraph<'_, 'tcx, graph::Normal> {
+ self.constraint_graph.region_graph(&self.constraints, self.universal_regions.fr_static)
+ }
+
+ /// Returns whether the given region is considered live at all points: whether it is a
+ /// placeholder or a free region.
+ pub(crate) fn is_region_live_at_all_points(&self, region: RegionVid) -> bool {
+ // FIXME: there must be a cleaner way to find this information. At least, when
+ // higher-ranked subtyping is abstracted away from the borrowck main path, we'll only
+ // need to check whether this is a universal region.
+ let origin = self.region_definition(region).origin;
+ let live_at_all_points = matches!(
+ origin,
+ NllRegionVariableOrigin::Placeholder(_) | NllRegionVariableOrigin::FreeRegion
+ );
+ live_at_all_points
+ }
+
+ /// Returns whether the `loan_idx` is live at the given `location`: whether its issuing
+ /// region is contained within the type of a variable that is live at this point.
+ /// Note: for now, the sets of live loans is only available when using `-Zpolonius=next`.
+ pub(crate) fn is_loan_live_at(&self, loan_idx: BorrowIndex, location: Location) -> bool {
+ let point = self.liveness_constraints.point_from_location(location);
+ self.live_loans.contains(point, loan_idx)
+ }
}
impl<'tcx> RegionDefinition<'tcx> {