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); } }