rustc_infer/infer/outlives/
mod.rs
1use rustc_data_structures::undo_log::UndoLogs;
4use rustc_middle::traits::query::{NoSolution, OutlivesBound};
5use rustc_middle::ty;
6use tracing::instrument;
7
8use self::env::OutlivesEnvironment;
9use super::region_constraints::{RegionConstraintData, UndoLog};
10use super::{InferCtxt, RegionResolutionError, SubregionOrigin};
11use crate::infer::free_regions::RegionRelations;
12use crate::infer::lexical_region_resolve;
13
14pub mod env;
15pub mod for_liveness;
16pub mod obligations;
17pub mod test_type_match;
18pub(crate) mod verify;
19
20#[instrument(level = "debug", skip(param_env), ret)]
21pub fn explicit_outlives_bounds<'tcx>(
22 param_env: ty::ParamEnv<'tcx>,
23) -> impl Iterator<Item = OutlivesBound<'tcx>> + 'tcx {
24 param_env
25 .caller_bounds()
26 .into_iter()
27 .filter_map(ty::Clause::as_region_outlives_clause)
28 .filter_map(ty::Binder::no_bound_vars)
29 .map(|ty::OutlivesPredicate(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a))
30}
31
32impl<'tcx> InferCtxt<'tcx> {
33 #[must_use]
42 pub fn resolve_regions_with_normalize(
43 &self,
44 outlives_env: &OutlivesEnvironment<'tcx>,
45 deeply_normalize_ty: impl Fn(
46 ty::PolyTypeOutlivesPredicate<'tcx>,
47 SubregionOrigin<'tcx>,
48 ) -> Result<ty::PolyTypeOutlivesPredicate<'tcx>, NoSolution>,
49 ) -> Vec<RegionResolutionError<'tcx>> {
50 match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) {
51 Ok(()) => {}
52 Err((clause, origin)) => {
53 return vec![RegionResolutionError::CannotNormalize(clause, origin)];
54 }
55 };
56
57 let storage = {
58 let mut inner = self.inner.borrow_mut();
59 let inner = &mut *inner;
60 assert!(
61 self.tainted_by_errors().is_some() || inner.region_obligations.is_empty(),
62 "region_obligations not empty: {:#?}",
63 inner.region_obligations
64 );
65 assert!(!UndoLogs::<UndoLog<'_>>::in_snapshot(&inner.undo_log));
66 inner.region_constraint_storage.take().expect("regions already resolved")
67 };
68
69 let region_rels = &RegionRelations::new(self.tcx, outlives_env.free_region_map());
70
71 let (lexical_region_resolutions, errors) =
72 lexical_region_resolve::resolve(region_rels, storage.var_infos, storage.data);
73
74 let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
75 assert!(old_value.is_none());
76
77 errors
78 }
79
80 pub fn take_and_reset_region_constraints(&self) -> RegionConstraintData<'tcx> {
91 assert!(
92 self.inner.borrow().region_obligations.is_empty(),
93 "region_obligations not empty: {:#?}",
94 self.inner.borrow().region_obligations
95 );
96
97 self.inner.borrow_mut().unwrap_region_constraints().take_and_reset_data()
98 }
99
100 pub fn with_region_constraints<R>(
102 &self,
103 op: impl FnOnce(&RegionConstraintData<'tcx>) -> R,
104 ) -> R {
105 let mut inner = self.inner.borrow_mut();
106 op(inner.unwrap_region_constraints().data())
107 }
108}