use ena::undo_log::UndoLogs;
use rustc_type_ir::{OutlivesPredicate, TypeVisitableExt};
use tracing::{debug, instrument};
use crate::next_solver::{
ArgOutlivesPredicate, GenericArgKind, Region, RegionOutlivesPredicate, Ty,
infer::{InferCtxt, TypeOutlivesConstraint, snapshot::undo_log::UndoLog},
};
impl<'db> InferCtxt<'db> {
pub fn register_outlives_constraint(
&self,
OutlivesPredicate(arg, r2): ArgOutlivesPredicate<'db>,
) {
match arg.kind() {
GenericArgKind::Lifetime(r1) => {
self.register_region_outlives_constraint(OutlivesPredicate(r1, r2));
}
GenericArgKind::Type(ty1) => {
self.register_type_outlives_constraint(ty1, r2);
}
GenericArgKind::Const(_) => unreachable!(),
}
}
pub fn register_region_outlives_constraint(
&self,
OutlivesPredicate(r_a, r_b): RegionOutlivesPredicate<'db>,
) {
// `'a: 'b` ==> `'b <= 'a`
self.sub_regions(r_b, r_a);
}
/// Registers that the given region obligation must be resolved
/// from within the scope of `body_id`. These regions are enqueued
/// and later processed by regionck, when full type information is
/// available (see `region_obligations` field for more
/// information).
#[instrument(level = "debug", skip(self))]
pub fn register_type_outlives_constraint_inner(&self, obligation: TypeOutlivesConstraint<'db>) {
let mut inner = self.inner.borrow_mut();
inner.undo_log.push(UndoLog::PushTypeOutlivesConstraint);
inner.region_obligations.push(obligation);
}
pub fn register_type_outlives_constraint(&self, sup_type: Ty<'db>, sub_region: Region<'db>) {
// `is_global` means the type has no params, infer, placeholder, or non-`'static`
// free regions. If the type has none of these things, then we can skip registering
// this outlives obligation since it has no components which affect lifetime
// checking in an interesting way.
if sup_type.is_global() {
return;
}
debug!(?sup_type, ?sub_region);
self.register_type_outlives_constraint_inner(TypeOutlivesConstraint {
sup_type,
sub_region,
});
}
pub fn register_region_assumption(&self, assumption: ArgOutlivesPredicate<'db>) {
let mut inner = self.inner.borrow_mut();
inner.undo_log.push(UndoLog::PushRegionAssumption);
inner.region_assumptions.push(assumption);
}
}