rustc_borrowck/region_infer/opaque_types/
region_ctxt.rs1use std::rc::Rc;
2
3use rustc_data_structures::frozen::Frozen;
4use rustc_index::IndexVec;
5use rustc_infer::infer::NllRegionVariableOrigin;
6use rustc_middle::ty::{RegionVid, UniverseIndex};
7use rustc_mir_dataflow::points::DenseLocationMap;
8
9use crate::BorrowckInferCtxt;
10use crate::constraints::ConstraintSccIndex;
11use crate::handle_placeholders::{SccAnnotations, region_definitions};
12use crate::region_infer::reverse_sccs::ReverseSccGraph;
13use crate::region_infer::values::RegionValues;
14use crate::region_infer::{ConstraintSccs, RegionDefinition, RegionTracker, Representative};
15use crate::type_check::MirTypeckRegionConstraints;
16use crate::type_check::free_region_relations::UniversalRegionRelations;
17use crate::universal_regions::UniversalRegions;
18
19pub(super) struct RegionCtxt<'a, 'tcx> {
22 pub(super) infcx: &'a BorrowckInferCtxt<'tcx>,
23 pub(super) definitions: Frozen<IndexVec<RegionVid, RegionDefinition<'tcx>>>,
24 pub(super) universal_region_relations: &'a UniversalRegionRelations<'tcx>,
25 pub(super) constraint_sccs: ConstraintSccs,
26 pub(super) scc_annotations: IndexVec<ConstraintSccIndex, RegionTracker>,
27 pub(super) rev_scc_graph: ReverseSccGraph,
28 pub(super) scc_values: RegionValues<ConstraintSccIndex>,
29}
30
31impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
32 pub(super) fn new(
37 infcx: &'a BorrowckInferCtxt<'tcx>,
38 universal_region_relations: &'a Frozen<UniversalRegionRelations<'tcx>>,
39 location_map: Rc<DenseLocationMap>,
40 constraints: &MirTypeckRegionConstraints<'tcx>,
41 ) -> RegionCtxt<'a, 'tcx> {
42 let universal_regions = &universal_region_relations.universal_regions;
43 let (definitions, _has_placeholders) = region_definitions(infcx, universal_regions);
44 let mut scc_annotations = SccAnnotations::init(&definitions);
45 let constraint_sccs = ConstraintSccs::new_with_annotation(
46 &constraints
47 .outlives_constraints
48 .graph(definitions.len())
49 .region_graph(&constraints.outlives_constraints, universal_regions.fr_static),
50 &mut scc_annotations,
51 );
52 let scc_annotations = scc_annotations.scc_to_annotation;
53
54 let placeholder_indices = Default::default();
57 let mut scc_values =
58 RegionValues::new(location_map, universal_regions.len(), placeholder_indices);
59 for variable in definitions.indices() {
60 let scc = constraint_sccs.scc(variable);
61 match definitions[variable].origin {
62 NllRegionVariableOrigin::FreeRegion => {
63 scc_values.add_element(scc, variable);
64 }
65 _ => {}
66 }
67 }
68
69 let rev_scc_graph = ReverseSccGraph::compute(&constraint_sccs, universal_regions);
70 RegionCtxt {
71 infcx,
72 definitions,
73 universal_region_relations,
74 constraint_sccs,
75 scc_annotations,
76 rev_scc_graph,
77 scc_values,
78 }
79 }
80
81 pub(super) fn representative(&self, vid: RegionVid) -> Representative {
82 let scc = self.constraint_sccs.scc(vid);
83 self.scc_annotations[scc].representative
84 }
85
86 pub(crate) fn max_placeholder_universe_reached(
87 &self,
88 scc: ConstraintSccIndex,
89 ) -> UniverseIndex {
90 self.scc_annotations[scc].max_placeholder_universe_reached()
91 }
92
93 pub(super) fn universal_regions(&self) -> &UniversalRegions<'tcx> {
94 &self.universal_region_relations.universal_regions
95 }
96
97 pub(super) fn eval_equal(&self, r1_vid: RegionVid, r2_vid: RegionVid) -> bool {
98 let r1 = self.constraint_sccs.scc(r1_vid);
99 let r2 = self.constraint_sccs.scc(r2_vid);
100
101 if r1 == r2 {
102 return true;
103 }
104
105 let universal_outlives = |sub, sup| {
106 self.scc_values.universal_regions_outlived_by(sub).all(|r1| {
107 self.scc_values
108 .universal_regions_outlived_by(sup)
109 .any(|r2| self.universal_region_relations.outlives(r2, r1))
110 })
111 };
112 universal_outlives(r1, r2) && universal_outlives(r2, r1)
113 }
114}