1use std::fmt;
4
5use rustc_data_structures::fx::FxHashSet;
6use rustc_data_structures::graph::implementation::{
7 Direction, Graph, INCOMING, NodeIndex, OUTGOING,
8};
9use rustc_data_structures::intern::Interned;
10use rustc_data_structures::unord::UnordSet;
11use rustc_index::{IndexSlice, IndexVec};
12use rustc_middle::ty::fold::{TypeFoldable, fold_regions};
13use rustc_middle::ty::{
14 self, ReBound, ReEarlyParam, ReErased, ReError, ReLateParam, RePlaceholder, ReStatic, ReVar,
15 Region, RegionVid, Ty, TyCtxt,
16};
17use rustc_middle::{bug, span_bug};
18use rustc_span::Span;
19use tracing::{debug, instrument};
20
21use super::outlives::test_type_match;
22use crate::infer::region_constraints::{
23 Constraint, GenericKind, RegionConstraintData, VarInfos, VerifyBound,
24};
25use crate::infer::{RegionRelations, RegionVariableOrigin, SubregionOrigin};
26
27#[instrument(level = "debug", skip(region_rels, var_infos, data))]
33pub(crate) fn resolve<'tcx>(
34 region_rels: &RegionRelations<'_, 'tcx>,
35 var_infos: VarInfos,
36 data: RegionConstraintData<'tcx>,
37) -> (LexicalRegionResolutions<'tcx>, Vec<RegionResolutionError<'tcx>>) {
38 let mut errors = vec![];
39 let mut resolver = LexicalResolver { region_rels, var_infos, data };
40 let values = resolver.infer_variable_values(&mut errors);
41 (values, errors)
42}
43
44#[derive(Clone)]
47pub(crate) struct LexicalRegionResolutions<'tcx> {
48 pub(crate) values: IndexVec<RegionVid, VarValue<'tcx>>,
49}
50
51#[derive(Copy, Clone, Debug)]
52pub(crate) enum VarValue<'tcx> {
53 Empty(ty::UniverseIndex),
60 Value(Region<'tcx>),
61 ErrorValue,
62}
63
64#[derive(Clone, Debug)]
65pub enum RegionResolutionError<'tcx> {
66 ConcreteFailure(SubregionOrigin<'tcx>, Region<'tcx>, Region<'tcx>),
70
71 GenericBoundFailure(SubregionOrigin<'tcx>, GenericKind<'tcx>, Region<'tcx>),
76
77 SubSupConflict(
83 RegionVid,
84 RegionVariableOrigin,
85 SubregionOrigin<'tcx>,
86 Region<'tcx>,
87 SubregionOrigin<'tcx>,
88 Region<'tcx>,
89 Vec<Span>, ),
91
92 UpperBoundUniverseConflict(
95 RegionVid,
96 RegionVariableOrigin,
97 ty::UniverseIndex, SubregionOrigin<'tcx>, Region<'tcx>, ),
101
102 CannotNormalize(ty::PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>),
103}
104
105impl<'tcx> RegionResolutionError<'tcx> {
106 pub fn origin(&self) -> &SubregionOrigin<'tcx> {
107 match self {
108 RegionResolutionError::ConcreteFailure(origin, _, _)
109 | RegionResolutionError::GenericBoundFailure(origin, _, _)
110 | RegionResolutionError::SubSupConflict(_, _, origin, _, _, _, _)
111 | RegionResolutionError::UpperBoundUniverseConflict(_, _, _, origin, _)
112 | RegionResolutionError::CannotNormalize(_, origin) => origin,
113 }
114 }
115}
116
117struct RegionAndOrigin<'tcx> {
118 region: Region<'tcx>,
119 origin: SubregionOrigin<'tcx>,
120}
121
122type RegionGraph<'tcx> = Graph<(), Constraint<'tcx>>;
123
124struct LexicalResolver<'cx, 'tcx> {
125 region_rels: &'cx RegionRelations<'cx, 'tcx>,
126 var_infos: VarInfos,
127 data: RegionConstraintData<'tcx>,
128}
129
130impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
131 fn tcx(&self) -> TyCtxt<'tcx> {
132 self.region_rels.tcx
133 }
134
135 fn infer_variable_values(
136 &mut self,
137 errors: &mut Vec<RegionResolutionError<'tcx>>,
138 ) -> LexicalRegionResolutions<'tcx> {
139 let mut var_data = self.construct_var_data();
140
141 let mut seen = UnordSet::default();
143 self.data.constraints.retain(|(constraint, _)| seen.insert(*constraint));
144
145 if cfg!(debug_assertions) {
146 self.dump_constraints();
147 }
148
149 self.expansion(&mut var_data);
150 self.collect_errors(&mut var_data, errors);
151 self.collect_var_errors(&var_data, errors);
152 var_data
153 }
154
155 fn num_vars(&self) -> usize {
156 self.var_infos.len()
157 }
158
159 fn construct_var_data(&self) -> LexicalRegionResolutions<'tcx> {
162 LexicalRegionResolutions {
163 values: IndexVec::from_fn_n(
164 |vid| {
165 let vid_universe = self.var_infos[vid].universe;
166 VarValue::Empty(vid_universe)
167 },
168 self.num_vars(),
169 ),
170 }
171 }
172
173 #[instrument(level = "debug", skip(self))]
174 fn dump_constraints(&self) {
175 for (idx, (constraint, _)) in self.data.constraints.iter().enumerate() {
176 debug!("Constraint {} => {:?}", idx, constraint);
177 }
178 }
179
180 fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
181 let mut constraints = IndexVec::from_elem(Vec::new(), &var_values.values);
189 let mut changes = Vec::new();
191 for (constraint, _) in &self.data.constraints {
192 match *constraint {
193 Constraint::RegSubVar(a_region, b_vid) => {
194 let b_data = var_values.value_mut(b_vid);
195
196 if self.expand_node(a_region, b_vid, b_data) {
197 changes.push(b_vid);
198 }
199 }
200 Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) {
201 VarValue::ErrorValue => continue,
202 VarValue::Empty(a_universe) => {
203 let b_data = var_values.value_mut(b_vid);
204
205 let changed = match *b_data {
206 VarValue::Empty(b_universe) => {
207 let ui = a_universe.min(b_universe);
210
211 debug!(
212 "Expanding value of {:?} \
213 from empty lifetime with universe {:?} \
214 to empty lifetime with universe {:?}",
215 b_vid, b_universe, ui
216 );
217
218 *b_data = VarValue::Empty(ui);
219 true
220 }
221 VarValue::Value(cur_region) => {
222 match *cur_region {
223 RePlaceholder(placeholder)
228 if !a_universe.can_name(placeholder.universe) =>
229 {
230 let lub = self.tcx().lifetimes.re_static;
231 debug!(
232 "Expanding value of {:?} from {:?} to {:?}",
233 b_vid, cur_region, lub
234 );
235
236 *b_data = VarValue::Value(lub);
237 true
238 }
239
240 _ => false,
241 }
242 }
243
244 VarValue::ErrorValue => false,
245 };
246
247 if changed {
248 changes.push(b_vid);
249 }
250 match b_data {
251 VarValue::Value(Region(Interned(ReStatic, _)))
252 | VarValue::ErrorValue => (),
253 _ => {
254 constraints[a_vid].push((a_vid, b_vid));
255 constraints[b_vid].push((a_vid, b_vid));
256 }
257 }
258 }
259 VarValue::Value(a_region) => {
260 let b_data = var_values.value_mut(b_vid);
261
262 if self.expand_node(a_region, b_vid, b_data) {
263 changes.push(b_vid);
264 }
265 match b_data {
266 VarValue::Value(Region(Interned(ReStatic, _)))
267 | VarValue::ErrorValue => (),
268 _ => {
269 constraints[a_vid].push((a_vid, b_vid));
270 constraints[b_vid].push((a_vid, b_vid));
271 }
272 }
273 }
274 },
275 Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => {
276 continue;
279 }
280 }
281 }
282
283 while let Some(vid) = changes.pop() {
284 constraints[vid].retain(|&(a_vid, b_vid)| {
285 let VarValue::Value(a_region) = *var_values.value(a_vid) else {
286 return false;
287 };
288 let b_data = var_values.value_mut(b_vid);
289 if self.expand_node(a_region, b_vid, b_data) {
290 changes.push(b_vid);
291 }
292 !matches!(
293 b_data,
294 VarValue::Value(Region(Interned(ReStatic, _))) | VarValue::ErrorValue
295 )
296 });
297 }
298 }
299
300 fn expand_node(
305 &self,
306 a_region: Region<'tcx>,
307 b_vid: RegionVid,
308 b_data: &mut VarValue<'tcx>,
309 ) -> bool {
310 debug!("expand_node({:?}, {:?} == {:?})", a_region, b_vid, b_data);
311
312 match *b_data {
313 VarValue::Empty(empty_ui) => {
314 let lub = match *a_region {
315 RePlaceholder(placeholder) => {
316 if empty_ui.can_name(placeholder.universe) {
320 ty::Region::new_placeholder(self.tcx(), placeholder)
321 } else {
322 self.tcx().lifetimes.re_static
323 }
324 }
325
326 _ => a_region,
327 };
328
329 debug!("Expanding value of {:?} from empty lifetime to {:?}", b_vid, lub);
330
331 *b_data = VarValue::Value(lub);
332 true
333 }
334 VarValue::Value(cur_region) => {
335 let b_universe = self.var_infos[b_vid].universe;
339
340 let mut lub = self.lub_concrete_regions(a_region, cur_region);
341 if lub == cur_region {
342 return false;
343 }
344
345 if let ty::RePlaceholder(p) = *lub
355 && b_universe.cannot_name(p.universe)
356 {
357 lub = self.tcx().lifetimes.re_static;
358 }
359
360 debug!("Expanding value of {:?} from {:?} to {:?}", b_vid, cur_region, lub);
361
362 *b_data = VarValue::Value(lub);
363 true
364 }
365
366 VarValue::ErrorValue => false,
367 }
368 }
369
370 fn sub_region_values(&self, a: VarValue<'tcx>, b: VarValue<'tcx>) -> bool {
372 match (a, b) {
373 (VarValue::ErrorValue, _) | (_, VarValue::ErrorValue) => return true,
375 (VarValue::Empty(a_ui), VarValue::Empty(b_ui)) => {
376 a_ui.min(b_ui) == b_ui
379 }
380 (VarValue::Value(a), VarValue::Empty(_)) => {
381 match *a {
382 ReError(_) => false,
385
386 ReBound(..) | ReErased => {
387 bug!("cannot relate region: {:?}", a);
388 }
389
390 ReVar(v_id) => {
391 span_bug!(
392 self.var_infos[v_id].origin.span(),
393 "lub_concrete_regions invoked with non-concrete region: {:?}",
394 a
395 );
396 }
397
398 ReStatic | ReEarlyParam(_) | ReLateParam(_) => {
399 false
405 }
406
407 RePlaceholder(_) => {
408 false
410 }
411 }
412 }
413 (VarValue::Empty(a_ui), VarValue::Value(b)) => {
414 match *b {
415 ReError(_) => false,
418
419 ReBound(..) | ReErased => {
420 bug!("cannot relate region: {:?}", b);
421 }
422
423 ReVar(v_id) => {
424 span_bug!(
425 self.var_infos[v_id].origin.span(),
426 "lub_concrete_regions invoked with non-concrete regions: {:?}",
427 b
428 );
429 }
430
431 ReStatic | ReEarlyParam(_) | ReLateParam(_) => {
432 true
436 }
437
438 RePlaceholder(placeholder) => {
439 return a_ui.can_name(placeholder.universe);
443 }
444 }
445 }
446 (VarValue::Value(a), VarValue::Value(b)) => self.sub_concrete_regions(a, b),
447 }
448 }
449
450 #[instrument(level = "trace", skip(self))]
452 fn sub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> bool {
453 let tcx = self.tcx();
454 let sub_free_regions = |r1, r2| self.region_rels.free_regions.sub_free_regions(tcx, r1, r2);
455
456 if b.is_free() && sub_free_regions(tcx.lifetimes.re_static, b) {
459 return true;
460 }
461
462 if a.is_free() && b.is_free() {
468 return sub_free_regions(a, b);
469 }
470
471 self.lub_concrete_regions(a, b) == b
474 }
475
476 #[instrument(level = "trace", skip(self), ret)]
482 fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
483 match (*a, *b) {
484 (ReBound(..), _) | (_, ReBound(..)) | (ReErased, _) | (_, ReErased) => {
485 bug!("cannot relate region: LUB({:?}, {:?})", a, b);
486 }
487
488 (ReVar(v_id), _) | (_, ReVar(v_id)) => {
489 span_bug!(
490 self.var_infos[v_id].origin.span(),
491 "lub_concrete_regions invoked with non-concrete \
492 regions: {:?}, {:?}",
493 a,
494 b
495 );
496 }
497
498 (ReError(_), _) => a,
499
500 (_, ReError(_)) => b,
501
502 (ReStatic, _) | (_, ReStatic) => {
503 self.tcx().lifetimes.re_static
505 }
506
507 (ReEarlyParam(_) | ReLateParam(_), ReEarlyParam(_) | ReLateParam(_)) => {
508 self.region_rels.lub_param_regions(a, b)
509 }
510
511 (RePlaceholder(..), _) | (_, RePlaceholder(..)) => {
514 if a == b {
515 a
516 } else {
517 self.tcx().lifetimes.re_static
518 }
519 }
520 }
521 }
522
523 #[instrument(skip(self, var_data, errors))]
527 fn collect_errors(
528 &self,
529 var_data: &mut LexicalRegionResolutions<'tcx>,
530 errors: &mut Vec<RegionResolutionError<'tcx>>,
531 ) {
532 for (constraint, origin) in &self.data.constraints {
533 debug!(?constraint, ?origin);
534 match *constraint {
535 Constraint::RegSubVar(..) | Constraint::VarSubVar(..) => {
536 }
538
539 Constraint::RegSubReg(sub, sup) => {
540 if self.sub_concrete_regions(sub, sup) {
541 continue;
542 }
543
544 debug!(
545 "region error at {:?}: \
546 cannot verify that {:?} <= {:?}",
547 origin, sub, sup
548 );
549
550 errors.push(RegionResolutionError::ConcreteFailure(
551 (*origin).clone(),
552 sub,
553 sup,
554 ));
555 }
556
557 Constraint::VarSubReg(a_vid, b_region) => {
558 let a_data = var_data.value_mut(a_vid);
559 debug!("contraction: {:?} == {:?}, {:?}", a_vid, a_data, b_region);
560
561 let VarValue::Value(a_region) = *a_data else {
562 continue;
563 };
564
565 if !self.sub_concrete_regions(a_region, b_region) {
569 debug!(
570 "region error at {:?}: \
571 cannot verify that {:?}={:?} <= {:?}",
572 origin, a_vid, a_region, b_region
573 );
574 *a_data = VarValue::ErrorValue;
575 }
576 }
577 }
578 }
579
580 for verify in &self.data.verifys {
581 debug!("collect_errors: verify={:?}", verify);
582 let sub = var_data.normalize(self.tcx(), verify.region);
583
584 let verify_kind_ty = verify.kind.to_ty(self.tcx());
585 let verify_kind_ty = var_data.normalize(self.tcx(), verify_kind_ty);
586 if self.bound_is_met(&verify.bound, var_data, verify_kind_ty, sub) {
587 continue;
588 }
589
590 debug!(
591 "collect_errors: region error at {:?}: \
592 cannot verify that {:?} <= {:?}",
593 verify.origin, verify.region, verify.bound
594 );
595
596 errors.push(RegionResolutionError::GenericBoundFailure(
597 verify.origin.clone(),
598 verify.kind,
599 sub,
600 ));
601 }
602 }
603
604 fn collect_var_errors(
607 &self,
608 var_data: &LexicalRegionResolutions<'tcx>,
609 errors: &mut Vec<RegionResolutionError<'tcx>>,
610 ) {
611 debug!("collect_var_errors, var_data = {:#?}", var_data.values);
612
613 let mut dup_vec = IndexVec::from_elem_n(None, self.num_vars());
625
626 let mut graph = None;
629
630 for (node_vid, value) in var_data.values.iter_enumerated() {
631 match *value {
632 VarValue::Empty(_) | VarValue::Value(_) => { }
633 VarValue::ErrorValue => {
634 let g = graph.get_or_insert_with(|| self.construct_graph());
663 self.collect_error_for_expanding_node(g, &mut dup_vec, node_vid, errors);
664 }
665 }
666 }
667 }
668
669 fn construct_graph(&self) -> RegionGraph<'tcx> {
670 let num_vars = self.num_vars();
671
672 let mut graph = Graph::new();
673
674 for _ in 0..num_vars {
675 graph.add_node(());
676 }
677
678 let dummy_source = graph.add_node(());
684 let dummy_sink = graph.add_node(());
685
686 for (constraint, _) in &self.data.constraints {
687 match *constraint {
688 Constraint::VarSubVar(a_id, b_id) => {
689 graph.add_edge(NodeIndex(a_id.index()), NodeIndex(b_id.index()), *constraint);
690 }
691 Constraint::RegSubVar(_, b_id) => {
692 graph.add_edge(dummy_source, NodeIndex(b_id.index()), *constraint);
693 }
694 Constraint::VarSubReg(a_id, _) => {
695 graph.add_edge(NodeIndex(a_id.index()), dummy_sink, *constraint);
696 }
697 Constraint::RegSubReg(..) => {
698 }
701 }
702 }
703
704 graph
705 }
706
707 fn collect_error_for_expanding_node(
708 &self,
709 graph: &RegionGraph<'tcx>,
710 dup_vec: &mut IndexSlice<RegionVid, Option<RegionVid>>,
711 node_idx: RegionVid,
712 errors: &mut Vec<RegionResolutionError<'tcx>>,
713 ) {
714 let (mut lower_bounds, lower_vid_bounds, lower_dup) =
717 self.collect_bounding_regions(graph, node_idx, INCOMING, Some(dup_vec));
718 let (mut upper_bounds, _, upper_dup) =
719 self.collect_bounding_regions(graph, node_idx, OUTGOING, Some(dup_vec));
720
721 if lower_dup || upper_dup {
722 return;
723 }
724
725 fn region_order_key(x: &RegionAndOrigin<'_>) -> u8 {
729 match *x.region {
730 ReEarlyParam(_) => 0,
731 ReLateParam(_) => 1,
732 _ => 2,
733 }
734 }
735 lower_bounds.sort_by_key(region_order_key);
736 upper_bounds.sort_by_key(region_order_key);
737
738 let node_universe = self.var_infos[node_idx].universe;
739
740 for lower_bound in &lower_bounds {
741 let effective_lower_bound = if let ty::RePlaceholder(p) = *lower_bound.region {
742 if node_universe.cannot_name(p.universe) {
743 self.tcx().lifetimes.re_static
744 } else {
745 lower_bound.region
746 }
747 } else {
748 lower_bound.region
749 };
750
751 for upper_bound in &upper_bounds {
752 if !self.sub_concrete_regions(effective_lower_bound, upper_bound.region) {
753 let origin = self.var_infos[node_idx].origin;
754 debug!(
755 "region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \
756 sup: {:?}",
757 origin, node_idx, lower_bound.region, upper_bound.region
758 );
759
760 errors.push(RegionResolutionError::SubSupConflict(
761 node_idx,
762 origin,
763 lower_bound.origin.clone(),
764 lower_bound.region,
765 upper_bound.origin.clone(),
766 upper_bound.region,
767 vec![],
768 ));
769 return;
770 }
771 }
772 }
773
774 #[allow(rustc::potential_query_instability)]
782 let min_universe = lower_vid_bounds
783 .into_iter()
784 .map(|vid| self.var_infos[vid].universe)
785 .min()
786 .expect("lower_vid_bounds should at least include `node_idx`");
787
788 for upper_bound in &upper_bounds {
789 if let ty::RePlaceholder(p) = *upper_bound.region {
790 if min_universe.cannot_name(p.universe) {
791 let origin = self.var_infos[node_idx].origin;
792 errors.push(RegionResolutionError::UpperBoundUniverseConflict(
793 node_idx,
794 origin,
795 min_universe,
796 upper_bound.origin.clone(),
797 upper_bound.region,
798 ));
799 return;
800 }
801 }
802 }
803
804 assert!(
807 self.tcx().dcx().has_errors().is_some(),
808 "collect_error_for_expanding_node() could not find error for var {node_idx:?} in \
809 universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \
810 upper_bounds={upper_bounds:#?}",
811 );
812 }
813
814 fn collect_bounding_regions(
826 &self,
827 graph: &RegionGraph<'tcx>,
828 orig_node_idx: RegionVid,
829 dir: Direction,
830 mut dup_vec: Option<&mut IndexSlice<RegionVid, Option<RegionVid>>>,
831 ) -> (Vec<RegionAndOrigin<'tcx>>, FxHashSet<RegionVid>, bool) {
832 struct WalkState<'tcx> {
833 set: FxHashSet<RegionVid>,
834 stack: Vec<RegionVid>,
835 result: Vec<RegionAndOrigin<'tcx>>,
836 dup_found: bool,
837 }
838 let mut state = WalkState {
839 set: Default::default(),
840 stack: vec![orig_node_idx],
841 result: Vec::new(),
842 dup_found: false,
843 };
844 state.set.insert(orig_node_idx);
845
846 process_edges(&self.data, &mut state, graph, orig_node_idx, dir);
849
850 while let Some(node_idx) = state.stack.pop() {
851 if let Some(dup_vec) = &mut dup_vec {
853 if dup_vec[node_idx].is_none() {
854 dup_vec[node_idx] = Some(orig_node_idx);
855 } else if dup_vec[node_idx] != Some(orig_node_idx) {
856 state.dup_found = true;
857 }
858
859 debug!(
860 "collect_concrete_regions(orig_node_idx={:?}, node_idx={:?})",
861 orig_node_idx, node_idx
862 );
863 }
864
865 process_edges(&self.data, &mut state, graph, node_idx, dir);
866 }
867
868 let WalkState { result, dup_found, set, .. } = state;
869 return (result, set, dup_found);
870
871 fn process_edges<'tcx>(
872 this: &RegionConstraintData<'tcx>,
873 state: &mut WalkState<'tcx>,
874 graph: &RegionGraph<'tcx>,
875 source_vid: RegionVid,
876 dir: Direction,
877 ) {
878 debug!("process_edges(source_vid={:?}, dir={:?})", source_vid, dir);
879
880 let source_node_index = NodeIndex(source_vid.index());
881 for (_, edge) in graph.adjacent_edges(source_node_index, dir) {
882 match edge.data {
883 Constraint::VarSubVar(from_vid, to_vid) => {
884 let opp_vid = if from_vid == source_vid { to_vid } else { from_vid };
885 if state.set.insert(opp_vid) {
886 state.stack.push(opp_vid);
887 }
888 }
889
890 Constraint::RegSubVar(region, _) | Constraint::VarSubReg(_, region) => {
891 let origin = this
892 .constraints
893 .iter()
894 .find(|(c, _)| *c == edge.data)
895 .unwrap()
896 .1
897 .clone();
898 state.result.push(RegionAndOrigin { region, origin });
899 }
900
901 Constraint::RegSubReg(..) => panic!(
902 "cannot reach reg-sub-reg edge in region inference \
903 post-processing"
904 ),
905 }
906 }
907 }
908 }
909
910 fn bound_is_met(
911 &self,
912 bound: &VerifyBound<'tcx>,
913 var_values: &LexicalRegionResolutions<'tcx>,
914 generic_ty: Ty<'tcx>,
915 min: ty::Region<'tcx>,
916 ) -> bool {
917 if let ty::ReError(_) = *min {
918 return true;
919 }
920
921 match bound {
922 VerifyBound::IfEq(verify_if_eq_b) => {
923 let verify_if_eq_b = var_values.normalize(self.region_rels.tcx, *verify_if_eq_b);
924 match test_type_match::extract_verify_if_eq(self.tcx(), &verify_if_eq_b, generic_ty)
925 {
926 Some(r) => {
927 self.bound_is_met(&VerifyBound::OutlivedBy(r), var_values, generic_ty, min)
928 }
929
930 None => false,
931 }
932 }
933
934 VerifyBound::OutlivedBy(r) => {
935 let a = match *min {
936 ty::ReVar(rid) => var_values.values[rid],
937 _ => VarValue::Value(min),
938 };
939 let b = match **r {
940 ty::ReVar(rid) => var_values.values[rid],
941 _ => VarValue::Value(*r),
942 };
943 self.sub_region_values(a, b)
944 }
945
946 VerifyBound::IsEmpty => match *min {
947 ty::ReVar(rid) => match var_values.values[rid] {
948 VarValue::ErrorValue => false,
949 VarValue::Empty(_) => true,
950 VarValue::Value(_) => false,
951 },
952 _ => false,
953 },
954
955 VerifyBound::AnyBound(bs) => {
956 bs.iter().any(|b| self.bound_is_met(b, var_values, generic_ty, min))
957 }
958
959 VerifyBound::AllBounds(bs) => {
960 bs.iter().all(|b| self.bound_is_met(b, var_values, generic_ty, min))
961 }
962 }
963 }
964}
965
966impl<'tcx> fmt::Debug for RegionAndOrigin<'tcx> {
967 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
968 write!(f, "RegionAndOrigin({:?},{:?})", self.region, self.origin)
969 }
970}
971
972impl<'tcx> LexicalRegionResolutions<'tcx> {
973 fn normalize<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
974 where
975 T: TypeFoldable<TyCtxt<'tcx>>,
976 {
977 fold_regions(tcx, value, |r, _db| self.resolve_region(tcx, r))
978 }
979
980 fn value(&self, rid: RegionVid) -> &VarValue<'tcx> {
981 &self.values[rid]
982 }
983
984 fn value_mut(&mut self, rid: RegionVid) -> &mut VarValue<'tcx> {
985 &mut self.values[rid]
986 }
987
988 pub(crate) fn resolve_region(
989 &self,
990 tcx: TyCtxt<'tcx>,
991 r: ty::Region<'tcx>,
992 ) -> ty::Region<'tcx> {
993 let result = match *r {
994 ty::ReVar(rid) => match self.values[rid] {
995 VarValue::Empty(_) => r,
996 VarValue::Value(r) => r,
997 VarValue::ErrorValue => tcx.lifetimes.re_static,
998 },
999 _ => r,
1000 };
1001 debug!("resolve_region({:?}) = {:?}", r, result);
1002 result
1003 }
1004}