rustc_infer/infer/outlives/
mod.rs1use std::iter;
4
5use rustc_data_structures::undo_log::UndoLogs;
6use rustc_middle::traits::query::{NoSolution, OutlivesBound};
7use rustc_middle::ty;
8use rustc_span::Span;
9use tracing::instrument;
10
11use self::env::OutlivesEnvironment;
12use super::region_constraints::{RegionConstraintData, UndoLog};
13use super::{InferCtxt, RegionResolutionError, SubregionOrigin};
14use crate::infer::free_regions::RegionRelations;
15use crate::infer::lexical_region_resolve;
16use crate::infer::region_constraints::ConstraintKind;
17
18pub mod env;
19pub mod obligations;
20pub mod test_type_match;
21pub(crate) mod verify;
22
23x;#[instrument(level = "debug", skip(param_env), ret)]
24pub fn explicit_outlives_bounds<'tcx>(
25 param_env: ty::ParamEnv<'tcx>,
26) -> impl Iterator<Item = OutlivesBound<'tcx>> {
27 param_env
28 .caller_bounds()
29 .into_iter()
30 .filter_map(ty::Clause::as_region_outlives_clause)
31 .filter_map(ty::Binder::no_bound_vars)
32 .map(|ty::OutlivesPredicate(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a))
33}
34
35impl<'tcx> InferCtxt<'tcx> {
36 #[must_use]
45 pub fn resolve_regions_with_normalize(
46 &self,
47 outlives_env: &OutlivesEnvironment<'tcx>,
48 deeply_normalize_ty: impl Fn(
49 ty::PolyTypeOutlivesPredicate<'tcx>,
50 SubregionOrigin<'tcx>,
51 ) -> Result<ty::PolyTypeOutlivesPredicate<'tcx>, NoSolution>,
52 span: Span,
53 ) -> Vec<RegionResolutionError<'tcx>> {
54 match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty, span) {
55 Ok(()) => {}
56 Err((clause, origin)) => {
57 return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[RegionResolutionError::CannotNormalize(clause, origin)]))vec![RegionResolutionError::CannotNormalize(clause, origin)];
58 }
59 };
60
61 let mut storage = {
62 let mut inner = self.inner.borrow_mut();
63 let inner = &mut *inner;
64 if !(self.tainted_by_errors().is_some() ||
inner.region_obligations.is_empty()) {
{
::core::panicking::panic_fmt(format_args!("region_obligations not empty: {0:#?}",
inner.region_obligations));
}
};assert!(
65 self.tainted_by_errors().is_some() || inner.region_obligations.is_empty(),
66 "region_obligations not empty: {:#?}",
67 inner.region_obligations,
68 );
69 if !!UndoLogs::<UndoLog<'_>>::in_snapshot(&inner.undo_log) {
::core::panicking::panic("assertion failed: !UndoLogs::<UndoLog<\'_>>::in_snapshot(&inner.undo_log)")
};assert!(!UndoLogs::<UndoLog<'_>>::in_snapshot(&inner.undo_log));
70 inner.region_constraint_storage.take().expect("regions already resolved")
71 };
72
73 storage.data.constraints = storage
74 .data
75 .constraints
76 .iter()
77 .flat_map(|(constraint, origin)| {
78 constraint.iter_outlives().zip(iter::repeat_with(|| origin.clone()))
79 })
80 .collect();
81
82 if self.tcx.sess.opts.unstable_opts.higher_ranked_assumptions {
85 storage.data.constraints.retain(|(c, _)| match c.kind {
86 ConstraintKind::RegSubReg => !outlives_env
87 .higher_ranked_assumptions()
88 .contains(&ty::OutlivesPredicate(c.sup.into(), c.sub)),
89
90 ConstraintKind::VarSubVar
91 | ConstraintKind::RegSubVar
92 | ConstraintKind::VarSubReg => true,
93
94 ConstraintKind::VarEqVar | ConstraintKind::VarEqReg | ConstraintKind::RegEqReg => {
95 ::core::panicking::panic("internal error: entered unreachable code");unreachable!();
96 }
97 });
98 }
99
100 let region_rels = &RegionRelations::new(self.tcx, outlives_env.free_region_map());
101
102 let (lexical_region_resolutions, errors) =
103 lexical_region_resolve::resolve(region_rels, storage.var_infos, storage.data);
104
105 let old_value = self.lexical_region_resolutions.replace(Some(lexical_region_resolutions));
106 if !old_value.is_none() {
::core::panicking::panic("assertion failed: old_value.is_none()")
};assert!(old_value.is_none());
107
108 errors
109 }
110
111 pub fn take_and_reset_region_constraints(&self) -> RegionConstraintData<'tcx> {
122 if !self.inner.borrow().region_obligations.is_empty() {
{
::core::panicking::panic_fmt(format_args!("region_obligations not empty: {0:#?}",
self.inner.borrow().region_obligations));
}
};assert!(
123 self.inner.borrow().region_obligations.is_empty(),
124 "region_obligations not empty: {:#?}",
125 self.inner.borrow().region_obligations
126 );
127 if !self.inner.borrow().region_assumptions.is_empty() {
{
::core::panicking::panic_fmt(format_args!("region_assumptions not empty: {0:#?}",
self.inner.borrow().region_assumptions));
}
};assert!(
128 self.inner.borrow().region_assumptions.is_empty(),
129 "region_assumptions not empty: {:#?}",
130 self.inner.borrow().region_assumptions
131 );
132
133 self.inner.borrow_mut().unwrap_region_constraints().take_and_reset_data()
134 }
135
136 pub fn with_region_constraints<R>(
138 &self,
139 op: impl FnOnce(&RegionConstraintData<'tcx>) -> R,
140 ) -> R {
141 let mut inner = self.inner.borrow_mut();
142 op(inner.unwrap_region_constraints().data())
143 }
144}