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