rustc_borrowck/
member_constraints.rs
1use std::hash::Hash;
2use std::ops::Index;
3
4use rustc_data_structures::captures::Captures;
5use rustc_data_structures::fx::FxIndexMap;
6use rustc_index::{IndexSlice, IndexVec};
7use rustc_middle::ty::{self, Ty};
8use rustc_span::Span;
9use tracing::instrument;
10
11#[derive(Debug)]
14pub(crate) struct MemberConstraintSet<'tcx, R>
15where
16 R: Copy + Eq,
17{
18 first_constraints: FxIndexMap<R, NllMemberConstraintIndex>,
21
22 constraints: IndexVec<NllMemberConstraintIndex, MemberConstraint<'tcx>>,
26
27 choice_regions: Vec<ty::RegionVid>,
31}
32
33#[derive(Debug)]
35pub(crate) struct MemberConstraint<'tcx> {
36 next_constraint: Option<NllMemberConstraintIndex>,
37
38 pub(crate) definition_span: Span,
40
41 pub(crate) hidden_ty: Ty<'tcx>,
43
44 pub(crate) key: ty::OpaqueTypeKey<'tcx>,
45
46 pub(crate) member_region_vid: ty::RegionVid,
48
49 start_index: usize,
51
52 end_index: usize,
54}
55
56rustc_index::newtype_index! {
57 #[debug_format = "MemberConstraintIndex({})"]
58 pub(crate) struct NllMemberConstraintIndex {}
59}
60
61impl Default for MemberConstraintSet<'_, ty::RegionVid> {
62 fn default() -> Self {
63 Self {
64 first_constraints: Default::default(),
65 constraints: Default::default(),
66 choice_regions: Default::default(),
67 }
68 }
69}
70
71impl<'tcx> MemberConstraintSet<'tcx, ty::RegionVid> {
72 pub(crate) fn is_empty(&self) -> bool {
73 self.constraints.is_empty()
74 }
75
76 #[instrument(level = "debug", skip(self))]
78 pub(crate) fn add_member_constraint(
79 &mut self,
80 key: ty::OpaqueTypeKey<'tcx>,
81 hidden_ty: Ty<'tcx>,
82 definition_span: Span,
83 member_region_vid: ty::RegionVid,
84 choice_regions: &[ty::RegionVid],
85 ) {
86 let next_constraint = self.first_constraints.get(&member_region_vid).cloned();
87 let start_index = self.choice_regions.len();
88 self.choice_regions.extend(choice_regions);
89 let end_index = self.choice_regions.len();
90 let constraint_index = self.constraints.push(MemberConstraint {
91 next_constraint,
92 member_region_vid,
93 definition_span,
94 hidden_ty,
95 key,
96 start_index,
97 end_index,
98 });
99 self.first_constraints.insert(member_region_vid, constraint_index);
100 }
101}
102
103impl<'tcx, R1> MemberConstraintSet<'tcx, R1>
104where
105 R1: Copy + Hash + Eq,
106{
107 pub(crate) fn into_mapped<R2>(
113 self,
114 mut map_fn: impl FnMut(R1) -> R2,
115 ) -> MemberConstraintSet<'tcx, R2>
116 where
117 R2: Copy + Hash + Eq,
118 {
119 let MemberConstraintSet { first_constraints, mut constraints, choice_regions } = self;
130
131 let mut first_constraints2 = FxIndexMap::default();
132 first_constraints2.reserve(first_constraints.len());
133
134 for (r1, start1) in first_constraints {
135 let r2 = map_fn(r1);
136 if let Some(&start2) = first_constraints2.get(&r2) {
137 append_list(&mut constraints, start1, start2);
138 }
139 first_constraints2.insert(r2, start1);
140 }
141
142 MemberConstraintSet { first_constraints: first_constraints2, constraints, choice_regions }
143 }
144}
145
146impl<'tcx, R> MemberConstraintSet<'tcx, R>
147where
148 R: Copy + Hash + Eq,
149{
150 pub(crate) fn all_indices(
151 &self,
152 ) -> impl Iterator<Item = NllMemberConstraintIndex> + Captures<'tcx> + '_ {
153 self.constraints.indices()
154 }
155
156 pub(crate) fn indices(
160 &self,
161 member_region_vid: R,
162 ) -> impl Iterator<Item = NllMemberConstraintIndex> + Captures<'tcx> + '_ {
163 let mut next = self.first_constraints.get(&member_region_vid).cloned();
164 std::iter::from_fn(move || -> Option<NllMemberConstraintIndex> {
165 if let Some(current) = next {
166 next = self.constraints[current].next_constraint;
167 Some(current)
168 } else {
169 None
170 }
171 })
172 }
173
174 pub(crate) fn choice_regions(&self, pci: NllMemberConstraintIndex) -> &[ty::RegionVid] {
181 let MemberConstraint { start_index, end_index, .. } = &self.constraints[pci];
182 &self.choice_regions[*start_index..*end_index]
183 }
184}
185
186impl<'tcx, R> Index<NllMemberConstraintIndex> for MemberConstraintSet<'tcx, R>
187where
188 R: Copy + Eq,
189{
190 type Output = MemberConstraint<'tcx>;
191
192 fn index(&self, i: NllMemberConstraintIndex) -> &MemberConstraint<'tcx> {
193 &self.constraints[i]
194 }
195}
196
197fn append_list(
214 constraints: &mut IndexSlice<NllMemberConstraintIndex, MemberConstraint<'_>>,
215 target_list: NllMemberConstraintIndex,
216 source_list: NllMemberConstraintIndex,
217) {
218 let mut p = target_list;
219 loop {
220 let r = &mut constraints[p];
221 match r.next_constraint {
222 Some(q) => p = q,
223 None => {
224 r.next_constraint = Some(source_list);
225 return;
226 }
227 }
228 }
229}