1use std::fmt;
4
5use rustc_data_structures::fx::FxHashSet;
6use rustc_data_structures::graph::linked_graph::{
7 Direction, INCOMING, LinkedGraph, 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, ConstraintKind, 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> = LinkedGraph<(), 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 (c, _) in &self.data.constraints {
191 match c.kind {
192 ConstraintKind::RegSubVar => {
193 let sup_vid = c.sup.as_var();
194 let sup_data = var_values.value_mut(sup_vid);
195
196 if self.expand_node(c.sub, sup_vid, sup_data) {
197 changes.push(sup_vid);
198 }
199 }
200 ConstraintKind::VarSubVar => {
201 let sub_vid = c.sub.as_var();
202 let sup_vid = c.sup.as_var();
203 match *var_values.value(sub_vid) {
204 VarValue::ErrorValue => continue,
205 VarValue::Empty(sub_universe) => {
206 let sup_data = var_values.value_mut(sup_vid);
207
208 let changed = match *sup_data {
209 VarValue::Empty(sup_universe) => {
210 let ui = sub_universe.min(sup_universe);
213
214 debug!(
215 "Expanding value of {:?} \
216 from empty lifetime with universe {:?} \
217 to empty lifetime with universe {:?}",
218 sup_vid, sup_universe, ui
219 );
220
221 *sup_data = VarValue::Empty(ui);
222 true
223 }
224 VarValue::Value(cur_region) => {
225 match cur_region.kind() {
226 RePlaceholder(placeholder)
231 if !sub_universe.can_name(placeholder.universe) =>
232 {
233 let lub = self.tcx().lifetimes.re_static;
234 debug!(
235 "Expanding value of {:?} from {:?} to {:?}",
236 sup_vid, cur_region, lub
237 );
238
239 *sup_data = VarValue::Value(lub);
240 true
241 }
242
243 _ => false,
244 }
245 }
246
247 VarValue::ErrorValue => false,
248 };
249
250 if changed {
251 changes.push(sup_vid);
252 }
253 match sup_data {
254 VarValue::Value(Region(Interned(ReStatic, _)))
255 | VarValue::ErrorValue => (),
256 _ => {
257 constraints[sub_vid].push((sub_vid, sup_vid));
258 constraints[sup_vid].push((sub_vid, sup_vid));
259 }
260 }
261 }
262 VarValue::Value(sub_region) => {
263 let sup_data = var_values.value_mut(sup_vid);
264
265 if self.expand_node(sub_region, sup_vid, sup_data) {
266 changes.push(sup_vid);
267 }
268 match sup_data {
269 VarValue::Value(Region(Interned(ReStatic, _)))
270 | VarValue::ErrorValue => (),
271 _ => {
272 constraints[sub_vid].push((sub_vid, sup_vid));
273 constraints[sup_vid].push((sub_vid, sup_vid));
274 }
275 }
276 }
277 }
278 }
279 ConstraintKind::RegSubReg | ConstraintKind::VarSubReg => {
280 continue;
283 }
284 }
285 }
286
287 while let Some(vid) = changes.pop() {
288 constraints[vid].retain(|&(a_vid, b_vid)| {
289 let VarValue::Value(a_region) = *var_values.value(a_vid) else {
290 return false;
291 };
292 let b_data = var_values.value_mut(b_vid);
293 if self.expand_node(a_region, b_vid, b_data) {
294 changes.push(b_vid);
295 }
296 !matches!(
297 b_data,
298 VarValue::Value(Region(Interned(ReStatic, _))) | VarValue::ErrorValue
299 )
300 });
301 }
302 }
303
304 fn expand_node(
309 &self,
310 a_region: Region<'tcx>,
311 b_vid: RegionVid,
312 b_data: &mut VarValue<'tcx>,
313 ) -> bool {
314 debug!("expand_node({:?}, {:?} == {:?})", a_region, b_vid, b_data);
315
316 match *b_data {
317 VarValue::Empty(empty_ui) => {
318 let lub = match a_region.kind() {
319 RePlaceholder(placeholder) => {
320 if empty_ui.can_name(placeholder.universe) {
324 ty::Region::new_placeholder(self.tcx(), placeholder)
325 } else {
326 self.tcx().lifetimes.re_static
327 }
328 }
329
330 _ => a_region,
331 };
332
333 debug!("Expanding value of {:?} from empty lifetime to {:?}", b_vid, lub);
334
335 *b_data = VarValue::Value(lub);
336 true
337 }
338 VarValue::Value(cur_region) => {
339 let b_universe = self.var_infos[b_vid].universe;
343
344 let mut lub = self.lub_concrete_regions(a_region, cur_region);
345 if lub == cur_region {
346 return false;
347 }
348
349 if let ty::RePlaceholder(p) = lub.kind()
359 && b_universe.cannot_name(p.universe)
360 {
361 lub = self.tcx().lifetimes.re_static;
362 }
363
364 debug!("Expanding value of {:?} from {:?} to {:?}", b_vid, cur_region, lub);
365
366 *b_data = VarValue::Value(lub);
367 true
368 }
369
370 VarValue::ErrorValue => false,
371 }
372 }
373
374 fn sub_region_values(&self, a: VarValue<'tcx>, b: VarValue<'tcx>) -> bool {
376 match (a, b) {
377 (VarValue::ErrorValue, _) | (_, VarValue::ErrorValue) => return true,
379 (VarValue::Empty(a_ui), VarValue::Empty(b_ui)) => {
380 a_ui.min(b_ui) == b_ui
383 }
384 (VarValue::Value(a), VarValue::Empty(_)) => {
385 match a.kind() {
386 ReError(_) => false,
389
390 ReBound(..) | ReErased => {
391 bug!("cannot relate region: {:?}", a);
392 }
393
394 ReVar(v_id) => {
395 span_bug!(
396 self.var_infos[v_id].origin.span(),
397 "lub_concrete_regions invoked with non-concrete region: {:?}",
398 a
399 );
400 }
401
402 ReStatic | ReEarlyParam(_) | ReLateParam(_) => {
403 false
409 }
410
411 RePlaceholder(_) => {
412 false
414 }
415 }
416 }
417 (VarValue::Empty(a_ui), VarValue::Value(b)) => {
418 match b.kind() {
419 ReError(_) => false,
422
423 ReBound(..) | ReErased => {
424 bug!("cannot relate region: {:?}", b);
425 }
426
427 ReVar(v_id) => {
428 span_bug!(
429 self.var_infos[v_id].origin.span(),
430 "lub_concrete_regions invoked with non-concrete regions: {:?}",
431 b
432 );
433 }
434
435 ReStatic | ReEarlyParam(_) | ReLateParam(_) => {
436 true
440 }
441
442 RePlaceholder(placeholder) => {
443 return a_ui.can_name(placeholder.universe);
447 }
448 }
449 }
450 (VarValue::Value(a), VarValue::Value(b)) => self.sub_concrete_regions(a, b),
451 }
452 }
453
454 #[instrument(level = "trace", skip(self))]
456 fn sub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> bool {
457 let tcx = self.tcx();
458 let sub_free_regions = |r1, r2| self.region_rels.free_regions.sub_free_regions(tcx, r1, r2);
459
460 if b.is_free() && sub_free_regions(tcx.lifetimes.re_static, b) {
463 return true;
464 }
465
466 if a.is_free() && b.is_free() {
472 return sub_free_regions(a, b);
473 }
474
475 self.lub_concrete_regions(a, b) == b
478 }
479
480 #[instrument(level = "trace", skip(self), ret)]
486 fn lub_concrete_regions(&self, a: Region<'tcx>, b: Region<'tcx>) -> Region<'tcx> {
487 match (a.kind(), b.kind()) {
488 (ReBound(..), _) | (_, ReBound(..)) | (ReErased, _) | (_, ReErased) => {
489 bug!("cannot relate region: LUB({:?}, {:?})", a, b);
490 }
491
492 (ReVar(v_id), _) | (_, ReVar(v_id)) => {
493 span_bug!(
494 self.var_infos[v_id].origin.span(),
495 "lub_concrete_regions invoked with non-concrete \
496 regions: {:?}, {:?}",
497 a,
498 b
499 );
500 }
501
502 (ReError(_), _) => a,
503
504 (_, ReError(_)) => b,
505
506 (ReStatic, _) | (_, ReStatic) => {
507 self.tcx().lifetimes.re_static
509 }
510
511 (ReEarlyParam(_) | ReLateParam(_), ReEarlyParam(_) | ReLateParam(_)) => {
512 self.region_rels.lub_param_regions(a, b)
513 }
514
515 (RePlaceholder(..), _) | (_, RePlaceholder(..)) => {
518 if a == b {
519 a
520 } else {
521 self.tcx().lifetimes.re_static
522 }
523 }
524 }
525 }
526
527 #[instrument(skip(self, var_data, errors))]
531 fn collect_errors(
532 &self,
533 var_data: &mut LexicalRegionResolutions<'tcx>,
534 errors: &mut Vec<RegionResolutionError<'tcx>>,
535 ) {
536 for (c, origin) in &self.data.constraints {
537 debug!(?c, ?origin);
538 match c.kind {
539 ConstraintKind::RegSubVar | ConstraintKind::VarSubVar => {
540 }
542
543 ConstraintKind::RegSubReg => {
544 if self.sub_concrete_regions(c.sub, c.sup) {
545 continue;
546 }
547
548 debug!(
549 "region error at {:?}: cannot verify that {:?} <= {:?}",
550 origin, c.sub, c.sup
551 );
552
553 errors.push(RegionResolutionError::ConcreteFailure(
554 (*origin).clone(),
555 c.sub,
556 c.sup,
557 ));
558 }
559
560 ConstraintKind::VarSubReg => {
561 let sub_vid = c.sub.as_var();
562 let sub_data = var_data.value_mut(sub_vid);
563 debug!("contraction: {:?} == {:?}, {:?}", sub_vid, sub_data, c.sup);
564
565 let VarValue::Value(sub_region) = *sub_data else {
566 continue;
567 };
568
569 if !self.sub_concrete_regions(sub_region, c.sup) {
573 debug!(
574 "region error at {:?}: cannot verify that {:?}={:?} <= {:?}",
575 origin, sub_vid, sub_region, c.sup
576 );
577 *sub_data = VarValue::ErrorValue;
578 }
579 }
580 }
581 }
582
583 for verify in &self.data.verifys {
584 debug!("collect_errors: verify={:?}", verify);
585 let sub = var_data.normalize(self.tcx(), verify.region);
586
587 let verify_kind_ty = verify.kind.to_ty(self.tcx());
588 let verify_kind_ty = var_data.normalize(self.tcx(), verify_kind_ty);
589 if self.bound_is_met(&verify.bound, var_data, verify_kind_ty, sub) {
590 continue;
591 }
592
593 debug!(
594 "collect_errors: region error at {:?}: \
595 cannot verify that {:?} <= {:?}",
596 verify.origin, verify.region, verify.bound
597 );
598
599 errors.push(RegionResolutionError::GenericBoundFailure(
600 verify.origin.clone(),
601 verify.kind,
602 sub,
603 ));
604 }
605 }
606
607 fn collect_var_errors(
610 &self,
611 var_data: &LexicalRegionResolutions<'tcx>,
612 errors: &mut Vec<RegionResolutionError<'tcx>>,
613 ) {
614 debug!("collect_var_errors, var_data = {:#?}", var_data.values);
615
616 let mut dup_vec = IndexVec::from_elem_n(None, self.num_vars());
628
629 let mut graph = None;
632
633 for (node_vid, value) in var_data.values.iter_enumerated() {
634 match *value {
635 VarValue::Empty(_) | VarValue::Value(_) => { }
636 VarValue::ErrorValue => {
637 let g = graph.get_or_insert_with(|| self.construct_graph());
666 self.collect_error_for_expanding_node(g, &mut dup_vec, node_vid, errors);
667 }
668 }
669 }
670 }
671
672 fn construct_graph(&self) -> RegionGraph<'tcx> {
673 let num_vars = self.num_vars();
674
675 let mut graph = LinkedGraph::new();
676
677 for _ in 0..num_vars {
678 graph.add_node(());
679 }
680
681 let dummy_source = graph.add_node(());
687 let dummy_sink = graph.add_node(());
688
689 for (c, _) in &self.data.constraints {
690 match c.kind {
691 ConstraintKind::VarSubVar => {
692 let sub_vid = c.sub.as_var();
693 let sup_vid = c.sup.as_var();
694 graph.add_edge(NodeIndex(sub_vid.index()), NodeIndex(sup_vid.index()), *c);
695 }
696 ConstraintKind::RegSubVar => {
697 graph.add_edge(dummy_source, NodeIndex(c.sup.as_var().index()), *c);
698 }
699 ConstraintKind::VarSubReg => {
700 graph.add_edge(NodeIndex(c.sub.as_var().index()), dummy_sink, *c);
701 }
702 ConstraintKind::RegSubReg => {
703 }
706 }
707 }
708
709 graph
710 }
711
712 fn collect_error_for_expanding_node(
713 &self,
714 graph: &RegionGraph<'tcx>,
715 dup_vec: &mut IndexSlice<RegionVid, Option<RegionVid>>,
716 node_idx: RegionVid,
717 errors: &mut Vec<RegionResolutionError<'tcx>>,
718 ) {
719 let (mut lower_bounds, lower_vid_bounds, lower_dup) =
722 self.collect_bounding_regions(graph, node_idx, INCOMING, Some(dup_vec));
723 let (mut upper_bounds, _, upper_dup) =
724 self.collect_bounding_regions(graph, node_idx, OUTGOING, Some(dup_vec));
725
726 if lower_dup || upper_dup {
727 return;
728 }
729
730 fn region_order_key(x: &RegionAndOrigin<'_>) -> u8 {
734 match x.region.kind() {
735 ReEarlyParam(_) => 0,
736 ReLateParam(_) => 1,
737 _ => 2,
738 }
739 }
740 lower_bounds.sort_by_key(region_order_key);
741 upper_bounds.sort_by_key(region_order_key);
742
743 let node_universe = self.var_infos[node_idx].universe;
744
745 for lower_bound in &lower_bounds {
746 let effective_lower_bound = if let ty::RePlaceholder(p) = lower_bound.region.kind() {
747 if node_universe.cannot_name(p.universe) {
748 self.tcx().lifetimes.re_static
749 } else {
750 lower_bound.region
751 }
752 } else {
753 lower_bound.region
754 };
755
756 for upper_bound in &upper_bounds {
757 if !self.sub_concrete_regions(effective_lower_bound, upper_bound.region) {
758 let origin = self.var_infos[node_idx].origin;
759 debug!(
760 "region inference error at {:?} for {:?}: SubSupConflict sub: {:?} \
761 sup: {:?}",
762 origin, node_idx, lower_bound.region, upper_bound.region
763 );
764
765 errors.push(RegionResolutionError::SubSupConflict(
766 node_idx,
767 origin,
768 lower_bound.origin.clone(),
769 lower_bound.region,
770 upper_bound.origin.clone(),
771 upper_bound.region,
772 vec![],
773 ));
774 return;
775 }
776 }
777 }
778
779 #[allow(rustc::potential_query_instability)]
787 let min_universe = lower_vid_bounds
788 .into_iter()
789 .map(|vid| self.var_infos[vid].universe)
790 .min()
791 .expect("lower_vid_bounds should at least include `node_idx`");
792
793 for upper_bound in &upper_bounds {
794 if let ty::RePlaceholder(p) = upper_bound.region.kind() {
795 if min_universe.cannot_name(p.universe) {
796 let origin = self.var_infos[node_idx].origin;
797 errors.push(RegionResolutionError::UpperBoundUniverseConflict(
798 node_idx,
799 origin,
800 min_universe,
801 upper_bound.origin.clone(),
802 upper_bound.region,
803 ));
804 return;
805 }
806 }
807 }
808
809 assert!(
812 self.tcx().dcx().has_errors().is_some(),
813 "collect_error_for_expanding_node() could not find error for var {node_idx:?} in \
814 universe {node_universe:?}, lower_bounds={lower_bounds:#?}, \
815 upper_bounds={upper_bounds:#?}",
816 );
817 }
818
819 fn collect_bounding_regions(
831 &self,
832 graph: &RegionGraph<'tcx>,
833 orig_node_idx: RegionVid,
834 dir: Direction,
835 mut dup_vec: Option<&mut IndexSlice<RegionVid, Option<RegionVid>>>,
836 ) -> (Vec<RegionAndOrigin<'tcx>>, FxHashSet<RegionVid>, bool) {
837 struct WalkState<'tcx> {
838 set: FxHashSet<RegionVid>,
839 stack: Vec<RegionVid>,
840 result: Vec<RegionAndOrigin<'tcx>>,
841 dup_found: bool,
842 }
843 let mut state = WalkState {
844 set: Default::default(),
845 stack: vec![orig_node_idx],
846 result: Vec::new(),
847 dup_found: false,
848 };
849 state.set.insert(orig_node_idx);
850
851 process_edges(&self.data, &mut state, graph, orig_node_idx, dir);
854
855 while let Some(node_idx) = state.stack.pop() {
856 if let Some(dup_vec) = &mut dup_vec {
858 if dup_vec[node_idx].is_none() {
859 dup_vec[node_idx] = Some(orig_node_idx);
860 } else if dup_vec[node_idx] != Some(orig_node_idx) {
861 state.dup_found = true;
862 }
863
864 debug!(
865 "collect_concrete_regions(orig_node_idx={:?}, node_idx={:?})",
866 orig_node_idx, node_idx
867 );
868 }
869
870 process_edges(&self.data, &mut state, graph, node_idx, dir);
871 }
872
873 let WalkState { result, dup_found, set, .. } = state;
874 return (result, set, dup_found);
875
876 fn process_edges<'tcx>(
877 this: &RegionConstraintData<'tcx>,
878 state: &mut WalkState<'tcx>,
879 graph: &RegionGraph<'tcx>,
880 source_vid: RegionVid,
881 dir: Direction,
882 ) {
883 debug!("process_edges(source_vid={:?}, dir={:?})", source_vid, dir);
884
885 let source_node_index = NodeIndex(source_vid.index());
886 for (_, edge) in graph.adjacent_edges(source_node_index, dir) {
887 let get_origin =
888 || this.constraints.iter().find(|(c, _)| *c == edge.data).unwrap().1.clone();
889
890 match edge.data.kind {
891 ConstraintKind::VarSubVar => {
892 let from_vid = edge.data.sub.as_var();
893 let to_vid = edge.data.sup.as_var();
894 let opp_vid = if from_vid == source_vid { to_vid } else { from_vid };
895 if state.set.insert(opp_vid) {
896 state.stack.push(opp_vid);
897 }
898 }
899
900 ConstraintKind::RegSubVar => {
901 let origin = get_origin();
902 state.result.push(RegionAndOrigin { region: edge.data.sub, origin });
903 }
904
905 ConstraintKind::VarSubReg => {
906 let origin = get_origin();
907 state.result.push(RegionAndOrigin { region: edge.data.sup, origin });
908 }
909
910 ConstraintKind::RegSubReg => panic!(
911 "cannot reach reg-sub-reg edge in region inference \
912 post-processing"
913 ),
914 }
915 }
916 }
917 }
918
919 fn bound_is_met(
920 &self,
921 bound: &VerifyBound<'tcx>,
922 var_values: &LexicalRegionResolutions<'tcx>,
923 generic_ty: Ty<'tcx>,
924 min: ty::Region<'tcx>,
925 ) -> bool {
926 if let ty::ReError(_) = min.kind() {
927 return true;
928 }
929
930 match bound {
931 VerifyBound::IfEq(verify_if_eq_b) => {
932 let verify_if_eq_b = var_values.normalize(self.region_rels.tcx, *verify_if_eq_b);
933 match test_type_match::extract_verify_if_eq(self.tcx(), &verify_if_eq_b, generic_ty)
934 {
935 Some(r) => {
936 self.bound_is_met(&VerifyBound::OutlivedBy(r), var_values, generic_ty, min)
937 }
938
939 None => false,
940 }
941 }
942
943 VerifyBound::OutlivedBy(r) => {
944 let a = match min.kind() {
945 ty::ReVar(rid) => var_values.values[rid],
946 _ => VarValue::Value(min),
947 };
948 let b = match r.kind() {
949 ty::ReVar(rid) => var_values.values[rid],
950 _ => VarValue::Value(*r),
951 };
952 self.sub_region_values(a, b)
953 }
954
955 VerifyBound::IsEmpty => match min.kind() {
956 ty::ReVar(rid) => match var_values.values[rid] {
957 VarValue::ErrorValue => false,
958 VarValue::Empty(_) => true,
959 VarValue::Value(_) => false,
960 },
961 _ => false,
962 },
963
964 VerifyBound::AnyBound(bs) => {
965 bs.iter().any(|b| self.bound_is_met(b, var_values, generic_ty, min))
966 }
967
968 VerifyBound::AllBounds(bs) => {
969 bs.iter().all(|b| self.bound_is_met(b, var_values, generic_ty, min))
970 }
971 }
972 }
973}
974
975impl<'tcx> fmt::Debug for RegionAndOrigin<'tcx> {
976 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
977 write!(f, "RegionAndOrigin({:?},{:?})", self.region, self.origin)
978 }
979}
980
981impl<'tcx> LexicalRegionResolutions<'tcx> {
982 fn normalize<T>(&self, tcx: TyCtxt<'tcx>, value: T) -> T
983 where
984 T: TypeFoldable<TyCtxt<'tcx>>,
985 {
986 fold_regions(tcx, value, |r, _db| self.resolve_region(tcx, r))
987 }
988
989 fn value(&self, rid: RegionVid) -> &VarValue<'tcx> {
990 &self.values[rid]
991 }
992
993 fn value_mut(&mut self, rid: RegionVid) -> &mut VarValue<'tcx> {
994 &mut self.values[rid]
995 }
996
997 pub(crate) fn resolve_region(
998 &self,
999 tcx: TyCtxt<'tcx>,
1000 r: ty::Region<'tcx>,
1001 ) -> ty::Region<'tcx> {
1002 let result = match r.kind() {
1003 ty::ReVar(rid) => match self.values[rid] {
1004 VarValue::Empty(_) => r,
1005 VarValue::Value(r) => r,
1006 VarValue::ErrorValue => tcx.lifetimes.re_static,
1007 },
1008 _ => r,
1009 };
1010 debug!("resolve_region({:?}) = {:?}", r, result);
1011 result
1012 }
1013}